在进行串口测试时,板上PA9为TX,接USB转串口的RX;PA10为板上RX,接USB转串口的TX,波特率设置为115200。接线之后的照片如下:
首先进行芯片温度读取测试,仍然使用上一篇ADC测试中的程序ADC1_TEMP:
/**
*
* @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
*/
#include <stdio.h>
#include "main.h"
/** @addtogroup ADC_ADC1_TEMP
* @{
*/
ADC_InitType ADC_InitStructure;
ADC_InitTypeEx ADC_InitStructureEx;
DMA_InitType DMA_InitStructure;
__IO uint16_t ADCConvertedValue;
void RCC_Configuration(void);
void Delay(__IO uint32_t nCount);
void USART1_Config(void);
#define Vc0 0 //X
#define Tc1 1.5f
/*V30 is the voltage value at 30 degree Celsius by factory default*/
uint16_t V30 = 0;
uint16_t ADvalue = 0;
uint32_t temp = 0;
#ifdef DEFINEFLOAT //Float
__IO float TempValue;
/*xx mv per degree Celsius by datasheet define*/
#define AVG_SLOPE 0.0041f
/**
*
@brief Cal temp use float result.
*/
float TempCal(uint16_t TempAdVal)
{
float Temperate;
/* Get the temperature inside the chip */
Temperate=((V30+Vc0-TempAdVal)*3.3/4095)/AVG_SLOPE+30.0f-Tc1;
return Temperate;
}
#else
__IO int16_t TempValue;
/*xx mv per degree Celsius by datasheet define*/
#define AVG_SLOPE 41
/**
* @brief Cal temp use integer result.
*/
int16_t TempCal(uint16_t TempAdVal)
{
int16_t Temperate;
/* Get the temperature inside the chip */
Temperate=(int16_t)((((V30+Vc0-TempAdVal)*33*10000)/(4095*10))/AVG_SLOPE+30-Tc1);
return Temperate;
}
#endif
/**
* @brief Main program
*/
int main(void)
{
/* System clocks configuration ---------------------------------------------*/
RCC_Configuration();
/* DMA1 channel1 configuration ----------------------------------------------*/
DMA_DeInit(DMA1_CH1);
DMA_InitStructure.PeriphAddr = (uint32_t)&ADC1->DAT;
DMA_InitStructure.MemAddr = (uint32_t)&ADCConvertedValue;
DMA_InitStructure.Direction = DMA_DIR_PERIPH_SRC;
DMA_InitStructure.BufSize = 1;
DMA_InitStructure.PeriphInc = DMA_PERIPH_INC_DISABLE;
DMA_InitStructure.DMA_MemoryInc = DMA_MEM_INC_DISABLE;
DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_SIZE_HALFWORD;
DMA_InitStructure.MemDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.CircularMode = DMA_MODE_CIRCULAR;
DMA_InitStructure.Priority = DMA_PRIORITY_HIGH;
DMA_InitStructure.Mem2Mem = DMA_M2M_DISABLE;
DMA_Init(DMA1_CH1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_EnableChannel(DMA1_CH1, ENABLE);
/* ADC1 configuration ------------------------------------------------------*/
ADC_InitStructure.WorkMode = ADC_WORKMODE_INDEPENDENT;
ADC_InitStructure.MultiChEn = DISABLE;
ADC_InitStructure.ContinueConvEn = ENABLE;
ADC_InitStructure.ExtTrigSelect = ADC_EXT_TRIGCONV_NONE;
ADC_InitStructure.DatAlign = ADC_DAT_ALIGN_R;
ADC_InitStructure.ChsNumber = 1;
ADC_Init(ADC1, &ADC_InitStructure);
/* ADC1 temp sensor enable */
ADC_EnableTempSensorVrefint(ENABLE);
ADC_InitStructureEx.VbatMinitEn = ENABLE;
ADC_InitStructureEx.DeepPowerModEn = DISABLE;
ADC_InitStructureEx.JendcIntEn = DISABLE;
ADC_InitStructureEx.EndcIntEn = DISABLE;
ADC_InitStructureEx.ClkMode = ADC_CTRL3_CKMOD_AHB;
ADC_InitStructureEx.CalAtuoLoadEn = DISABLE;
ADC_InitStructureEx.DifModCal = false;
ADC_InitStructureEx.ResBit = ADC_CTRL3_RES_12BIT;
ADC_InitStructureEx.SampSecondStyle = false;
ADC_InitEx(ADC1, &ADC_InitStructureEx);
/* ADC1 regular configuration */
ADC_ConfigRegularChannel(ADC1, ADC_CH_16, 1, ADC_SAMP_TIME_239CYCLES5);//ADC_CH_16£º²âζȣ¬ADC_CH_18£º²âÄÚ²¿1.2V»ù×¼
/* ADC1 temp sensor enable */
ADC_EnableTempSensorVrefint(ENABLE);
/* Enable ADC1 DMA */
ADC_EnableDMA(ADC1, ENABLE);
/* Enable ADC1 */
ADC_Enable(ADC1, ENABLE);
/*Check ADC Ready*/
while(ADC_GetFlagStatusNew(ADC1,ADC_FLAG_RDY) == RESET)
;
/* Start ADC1 calibration */
ADC_StartCalibration(ADC1);
/* Check the end of ADC1 calibration */
while (ADC_GetCalibrationStatus(ADC1))
;
/* Start ADC1 Software Conversion */
ADC_EnableSoftwareStartConv(ADC1, ENABLE);
/* Config Uart1 as Temperature output */
USART1_Config();
V30 = *(__IO uint32_t*)((uint32_t)0x1FFFF7D0);
while (1)
{
/* */
TempValue = TempCal(ADCConvertedValue);
#ifdef DEFINEFLOAT
printf("\r\n Temperature = %.3f C\r\n",TempValue);
#else
printf("\r\n Temperature = %d C\r\n",TempValue);
#endif
Delay(500);
}
}
/*
* @brief uart configure as 115200 8-N-1
*/
void USART1_Config(void)
{
GPIO_InitType GPIO_InitStructure;
USART_InitType USART_InitStructure;
/* configure USART1 clock*/
RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_USART1 | RCC_APB2_PERIPH_GPIOA, ENABLE);
/* USART1 GPIO config */
/* Configure USART1 Tx (PA.09) as alternate function push-pull */
GPIO_InitStructure.Pin = GPIO_PIN_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
/* Configure USART1 Rx (PA.10) as input floating */
GPIO_InitStructure.Pin = GPIO_PIN_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure);
/* USART1 work mode*/
USART_InitStructure.BaudRate = 115200;
USART_InitStructure.WordLength = USART_WL_8B;
USART_InitStructure.StopBits = USART_STPB_1;
USART_InitStructure.Parity = USART_PE_NO ;
USART_InitStructure.HardwareFlowControl = USART_HFCTRL_NONE;
USART_InitStructure.Mode = USART_MODE_RX | USART_MODE_TX;
USART_Init(USART1, &USART_InitStructure);
USART_Enable(USART1, ENABLE);
}
/* retarget the C library printf function to the USART */
int fputc(int ch, FILE* f)
{
USART_SendData(USART1, (uint8_t)ch);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXDE) == RESET)
;
return (ch);
}
/**
* @brief Delay funciton.
*/
void Delay(__IO uint32_t nCount)
{
for(; nCount != 0; nCount--);
}
/**
* @brief Configures the different system clocks.
*/
void RCC_Configuration(void)
{
/* Enable peripheral clocks ------------------------------------------------*/
/* Enable DMA1 clocks */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_DMA1, ENABLE);
/* Enable ADC1 clocks */
RCC_EnableAHBPeriphClk(RCC_AHB_PERIPH_ADC1,ENABLE);
/* RCC_ADCHCLK_DIV16*/
ADC_ConfigClk(ADC_CTRL3_CKMOD_AHB,RCC_ADCHCLK_DIV16);
RCC_ConfigAdc1mClk(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8); //selsect HSE as RCC ADC1M CLK Source
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file pointer to the source file name
* @param line assert_param error line source number
*/
void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
读取室温下的芯片温度如下:
再将手指置于芯片上进行升温,读取到的温度为:
之后也使用了ALGO程序进行测试串口的状态信息,程序如下:
/**
* @file main.c
* @author Nations
* @version v1.0.0
*
* @copyright Copyright (c) 2022, Nations Technologies Inc. All rights reserved.
*/
#include "n32a455.h"
#include "n32a455_rcc.h"
#include "n32a455_rng.h"
#include "n32a455_hash.h"
#include "n32a455_des.h"
#include "n32a455_aes.h"
#include "log.h"
#include <string.h>
#ifdef __IAR_ARM
#pragma pack(4)
#endif
/**
* @brief show some words(32bit) in hex format
*/
void DumpWords(const uint32_t* words, uint32_t len)
{
for (uint32_t i = 0; i < len; ++i)
{
log_info("0x%08x, ", words);
}
}
/**
* @brief show some bytes(8bit) in hex format
*/
void DumpBytes(const uint8_t* bytes, uint32_t len)
{
for (uint32_t i = 0; i < len; ++i)
{
log_info("%02x", bytes);
}
}
/**
* @brief Example for how to get a randon number by ALGO lib
*/
void TestRand(void)
{
uint32_t buf[8];
uint32_t seed[2] = {1, 2};
log_info("\n");
if (RNG_OK != GetPseudoRand_U32(buf, 8, seed))
{
log_error("GetPseudoRand_U32 failed.\n");
}
else
{
log_info("Pseudo random with seed 1,2: ");
DumpWords(buf, 8);
log_info("\n");
}
seed[0] = 3;
seed[1] = 4;
if (RNG_OK != GetPseudoRand_U32(buf, 8, seed))
{
log_error("GetPseudoRand_U32 failed.\n");
}
else
{
log_info("Pseudo random with seed 3,4: ");
DumpWords(buf, 8);
log_info("\n");
}
if (RNG_OK != GetTrueRand_U32(buf, 8))
{
log_error("GetTrueRand_U32 failed.\n");
}
else
{
log_info("True random: ");
DumpWords(buf, 8);
log_info("\n");
}
}
#define HASH_TEST_MSG "Hello!"
/**
* @brief Show how to calculate hash value by ALGO lib for a message
*/
void CalcHASH(const HASH_ALG* hashAlg, char* msg, uint8_t* result)
{
HASH_CTX ctx;
ctx.hashAlg = hashAlg;
ctx.sequence = HASH_SEQUENCE_FALSE;
if (HASH_Init_OK != HASH_Init(&ctx))
{
log_error("HASH_Init failed.\n");
return;
}
if (HASH_Start_OK != HASH_Start(&ctx))
{
log_error("HASH_Start failed.\n");
return;
}
if (HASH_Update_OK != HASH_Update(&ctx, (uint8_t*)msg, strlen(msg)))
{
log_error("HASH_Update failed.\n");
return;
}
if (HASH_Complete_OK != HASH_Complete(&ctx, result))
{
log_error("HASH_Complete failed.\n");
return;
}
}
/**
* @brief Show how to calculate SHA1 value by ALGO lib for a message
*/
void TestSHA1()
{
uint8_t result[20];
log_info("\n");
CalcHASH(HASH_ALG_SHA1, HASH_TEST_MSG, result);
log_info("SHA1 of message `%s` is: ", HASH_TEST_MSG);
DumpBytes(result, 20);
log_info("\n");
}
/**
* @brief Show how to calculate MD5 value by ALGO lib for a message
*/
void TestMD5()
{
uint8_t result[16];
log_info("\n");
CalcHASH(HASH_ALG_MD5, HASH_TEST_MSG, result);
log_info("MD5 of message `%s` is: ", HASH_TEST_MSG);
DumpBytes(result, 16);
log_info("\n");
}
/**
* @brief Show how to calculate SHA224 value by ALGO lib for a message
*/
void TestSHA224()
{
uint8_t result[28];
log_info("\n");
CalcHASH(HASH_ALG_SHA224, HASH_TEST_MSG, result);
log_info("SHA224 of message `%s` is: ", HASH_TEST_MSG);
DumpBytes(result, 28);
log_info("\n");
}
/**
* @brief Show how to calculate SHA256 value by ALGO lib for a message
*/
void TestSHA256()
{
uint8_t result[32];
log_info("\n");
CalcHASH(HASH_ALG_SHA256, HASH_TEST_MSG, result);
log_info("SHA256 of message `%s` is: ", HASH_TEST_MSG);
DumpBytes(result, 32);
log_info("\n");
}
/**
* @brief Show how to encrypt a message by DES, then decrypt it and compare the result.
*/
void TestDES(void)
{
DES_PARM DES_Parm;
#ifdef __IAR_ARM
uint8_t key[8] = {1, 2, 3, 4, 5, 6, 7, 8};
uint8_t plain[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
uint8_t cipher[8];
uint8_t plainOut[8];
#else
__align(4) uint8_t key[8] = {1, 2, 3, 4, 5, 6, 7, 8};
__align(4) uint8_t plain[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
__align(4) uint8_t cipher[8];
__align(4) uint8_t plainOut[8];
#endif
log_info("\n");
DES_Parm.in = (uint32_t*)plain;
DES_Parm.out = (uint32_t*)cipher;
DES_Parm.key = (uint32_t*)key;
DES_Parm.iv = NULL; // IV is not needed in ECB mode
DES_Parm.inWordLen = sizeof(plain) / sizeof(uint32_t);
DES_Parm.Mode = DES_ECB;
DES_Parm.En_De = DES_ENC;
DES_Parm.keyMode = DES_KEY;
// encrypt data
if (DES_Init_OK != DES_Init(&DES_Parm))
{
log_error("DES_Init failed.\n");
return;
}
if (DES_Crypto_OK != DES_Crypto(&DES_Parm))
{
log_error("DES_Crypto failed\n");
return;
}
log_info("DES ECB encrypt:\n");
log_info("key = ");
DumpBytes(key, sizeof(key));
log_info("\n");
log_info("plain = ");
DumpBytes(plain, sizeof(plain));
log_info("\n");
log_info("cipher = ");
DumpBytes(cipher, sizeof(cipher));
log_info("\n");
DES_Parm.in = (uint32_t*)cipher;
DES_Parm.out = (uint32_t*)plainOut;
DES_Parm.En_De = DES_DEC;
// decrypt data
if (DES_Init_OK != DES_Init(&DES_Parm))
{
log_error("DES_Init failed.\n");
return;
}
if (DES_Crypto_OK != DES_Crypto(&DES_Parm))
{
log_error("DES_Crypto failed\n");
return;
}
log_info("decrypt out = ");
DumpBytes(plainOut, 8);
log_info("\n");
if (memcmp(plain, plainOut, sizeof(plain)) != 0)
{
log_error("DES decrypt result do not equal plain data.\n");
while(1);
}
else
{
log_info("DES test OK!\n");
}
}
/**
* @brief Show how to encrypt a message by AES, then decrypt it and compare the result.
*/
void TestAES(void)
{
AES_PARM AES_Parm;
#ifdef __IAR_ARM
uint8_t key[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
uint8_t plain[16] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00};
uint8_t cipher[16];
uint8_t plainOut[16];
#else
__align(4) uint8_t key[16] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
__align(4) uint8_t plain[16] = {
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x00};
__align(4) uint8_t cipher[16];
__align(4) uint8_t plainOut[16];
#endif
log_info("\n");
AES_Parm.in = (uint32_t*)plain;
AES_Parm.out = (uint32_t*)cipher;
AES_Parm.key = (uint32_t*)key;
AES_Parm.iv = NULL; // IV is not needed in ECB mode
AES_Parm.inWordLen = sizeof(plain) / sizeof(uint32_t);
AES_Parm.keyWordLen = sizeof(key) / sizeof(uint32_t);
AES_Parm.Mode = AES_ECB;
AES_Parm.En_De = AES_ENC;
// encrypt data
if (AES_Init_OK != AES_Init(&AES_Parm))
{
log_error("AES_Init failed.\n");
return;
}
if (AES_Crypto_OK != AES_Crypto(&AES_Parm))
{
log_error("AES_Crypto failed\n");
return;
}
log_info("AES ECB encrypt:\n");
log_info("key = ");
DumpBytes(key, sizeof(key));
log_info("\n");
log_info("plain = ");
DumpBytes(plain, sizeof(plain));
log_info("\n");
log_info("cipher = ");
DumpBytes(cipher, sizeof(cipher));
log_info("\n");
AES_Parm.in = (uint32_t*)cipher;
AES_Parm.out = (uint32_t*)plainOut;
AES_Parm.En_De = AES_DEC;
// decrypt data
if (AES_Init_OK != AES_Init(&AES_Parm))
{
log_error("AES_Init failed.\n");
return;
}
if (AES_Crypto_OK != AES_Crypto(&AES_Parm))
{
log_error("AES_Crypto failed\n");
return;
}
log_info("decrypt out = ");
DumpBytes(plainOut, sizeof(plainOut));
log_info("\n");
if (memcmp(plain, plainOut, sizeof(plain)) != 0)
{
log_error("AES decrypt result do not equal plain data.\n");
while(1);
}
else
{
log_info("AES test OK!\n");
}
}
/**
* @brief main function.
*/
int main(void)
{
log_init();
log_info("-----------------------\nAlgorithm demo start.\n");
// RNG test
TestRand();
// HASH test
TestMD5();
TestSHA1();
TestSHA224();
TestSHA256();
// Cryptogram algorithm
TestDES();
TestAES();
log_info("\r\nALGO demo all test OK!\r\n");
while (1)
;
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file pointer to the source file name
* @param line assert_param error line source number
*/
void assert_failed(const uint8_t* expr, const uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
测试结果如下:
完成了串口通讯的测试。