stm32 hal库 串口中断与串口屏通信
·
串口屏开发较快,是电赛中比较好用的工具
我使用的是陶晶驰的7寸串口屏
官网上有许多的资料可供参考
0.不成功原因(都是我踩过的坑)
1.串口波特率不一致
2.use Microlib没有勾选
3.串口中断忘记开或者开错了
4.注意选择的串口(如果不是usart1,注意串口重定向和其他很多地方都要改成实际使用的串 口号)
1.cubemx配置

我使用串口一,配置为异步模式,波特率选择为9600,其余配置不动。
开启中断,优先级按需选取


时钟树配置,直接最大168输入,Enter自动配置

2.keil代码
stm32发送给串口屏的数据需要遵循一定的格式,例如要修改page0.t0.txt的值,可以使用
printf("page0.t1.txt=\"%d\"\xff\xff\xff", m);要以\xff\xff\xff结尾
变量定义
uint16_t m = 3100;
uint16_t RX;
uint16_t rx_data[256]; // 串口接收缓冲
uint16_t rx_cnt;
使能串口中断,开启接收
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RX, 1);
/* USER CODE END 2 */
while里面此处随便写写
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(500);
m=(m+1)%9000;
//printf("page0.t1.txt=\"%d\"\xff\xff\xff", m);
}
中断回调函数
使用帧头+数据+帧尾的方式传播,此处只传一个数据
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
rx_data[rx_cnt] = RX; //接收数据转存入数组
rx_cnt=rx_cnt+1;
HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin);
if (rx_data[rx_cnt-1] == 0x0A && rx_data[rx_cnt-3] == 0xFF) //判断接收数据的帧头帧尾
{
HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin);
printf("t1.txt=\"%d\"\xff\xff\xff",rx_data[rx_cnt-2]);//+rx_data[rx_cnt-2]
//将收到的数据发送回串口屏
rx_cnt =0;
memset(rx_data,0x00,sizeof(rx_data)); //清空数组
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RX, 1);//再开启中断
}
}
串口重定向,记得要勾选use microlib
// 串口重定向
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
3.HMI软件配置
配置页面大致介绍

某及次工程的串口屏串口中断回调函数代码,可参考
1
// 串口重定向
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
int fgetc(FILE *f)
{
uint8_t ch = 0;
HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
return ch;
}
// 波形种类:type=0---正弦波,type=1---方波,type=2---三角波,type=3---Sa波
//char wave_type[4][10] = {"正弦波","方波","三角波","Sa波"};
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart1)
{
rx_data[rx_cnt] = RX; //接收数据转存入数组
rx_cnt=rx_cnt+1;
//HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin);
if (rx_data[rx_cnt-1] == 0x0A && rx_data[rx_cnt-3] == 0xFF) //判断接收数据的帧头帧尾
{
//HAL_GPIO_TogglePin(LED_BLUE_GPIO_Port,LED_BLUE_Pin);
//printf("t1.txt=\"%d\"\xff\xff\xff",rx_data[rx_cnt-2]);//+rx_data[rx_cnt-2]
switch(rx_data[rx_cnt-2]) //判断接收数据的类型
{
case 0x01: // 开始测量---------单路信号高低电平、频率、波形、占空比
{
printf("page1.t4.txt=\"%d\"\xff\xff\xff",0); //高电平,单位mV
printf("page1.t6.txt=\"%d\"\xff\xff\xff",0); //低电平,单位mV
printf("page1.t8.txt=\"%d\"\xff\xff\xff",0); //频率,单位KHz
printf("page1.t10.txt=\"%s\"\xff\xff\xff",wave_type[type]); //波形类型,
printf("page1.t13.txt=\"%d\"\xff\xff\xff",0); //占空比,单位%
}
break;
case 0x02: // 锁相0度 spi发送波形种类和频率给fpga
{
}
break;
case 0x03: // 锁相45度
{
}
break;
case 0x04: // 锁相90度
{
}
break;
case 0x05: // 锁相180度
{
}
break;
case 0x06: // 双路信号测相位差
{
printf("page2.t2.txt=\"%d\"\xff\xff\xff",0); //相位差,单位度
printf("page2.t5.txt=\"%d\"\xff\xff\xff",0); //频率,单位KHz
}
break;
case 0x07: // 电容测量
{
printf("page3.t2.txt=\"%d\"\xff\xff\xff",0); //电容值,单位uF
}
break;
default:
break;
}
//将收到的数据发送回串口屏
rx_cnt =0;
memset(rx_data,0x00,sizeof(rx_data)); //清空数组
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RX, 1);//再开启中断
}
}
做23年h题时用的代码,用到了串口屏的数字控件


点击数字控件,然后


但是,感觉有一点点问题,这道题时,发送两位数时,会出现固定的误差20700,我直接减掉了。
其实也可以自己写一个数字控件的。
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart == &huart3)
{
rx_data[rx_cnt] = RX; //缓存数组
rx_cnt=rx_cnt+1;
if(rx_data[rx_cnt-3]==0xFF && rx_data[rx_cnt-1]==0x0A) // FF 99 0A
{
switch(rx_data[rx_cnt-2]) //当前接收的数据前一个
{
case 0x99:
{
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
if(angle>20000)
{
angle-=20700;
}
set_phase[0]=((angle*4096)/360)%4096;
printf("page0.t6.txt=\"%s\"\xff\xff\xff",wave[wave_c_a[0]]); //A
printf("page0.t8.txt=\"%d\"\xff\xff\xff",freq_a[0]); //A
printf("page0.t10.txt=\"%s\"\xff\xff\xff",wave[wave_c_b[0]]); //B
printf("page0.t12.txt=\"%d\"\xff\xff\xff",freq_b[0] ); //B
spi_flag = 0;
}
break;
default: // 一位数
{
angle=0; //初始化
angle = rx_data[rx_cnt-2]-48;
// if(angle > 10000)
// {
// angle=angle-22977*pow(10,(rx_cnt-3));
// }
}
break;
}
rx_cnt=0;
memset(rx_data,0x00,sizeof(rx_data));
rx_flag=0;
}
else if(rx_data[rx_cnt-5]==0xFF && rx_data[rx_cnt-1]==0x0A) // FF xx xx xx 0A 三位数
{
angle=0; //初始化
angle=(rx_data[rx_cnt-4]-48)*100 + (rx_data[rx_cnt-3]-48)*10 + rx_data[rx_cnt-2]-48;
rx_cnt=0;
memset(rx_data,0x00,sizeof(rx_data));
rx_flag=0;
}
else if(rx_data[rx_cnt-4]==0xFF && rx_data[rx_cnt-1]==0x0A) // FF xx xx 0A 两位数
{
angle=0; //初始化
angle=rx_data[rx_cnt-2]-48 + (rx_data[rx_cnt-3]-48)*10;
rx_cnt=0;
memset(rx_data,0x00,sizeof(rx_data));
rx_flag=0;
}
HAL_UART_Receive_IT(&huart3, (uint8_t *)&RX, 1);//
}
}
更多推荐
所有评论(0)