本帖最后由 enderman1 于 2019-5-29 19:08 编辑
四、串口指令_加强版(四则运算)
之前忽略了一个重要的点,就是串口指令的处理;虽然现在通过修改程序已经可以实现信号的四则运算,但是如何利用输入的串口指令进行四则运算是重点,这牵扯到了C语言中的数组操作部分。正好我利用了中午的时间完成了这个任务,并且总结了一些经验。
另外,这其实是一个独立的程序,后期用于移植到信号发生器上使用
PS.虽然完成了,但是我并不感觉我的实现方法多么的高明,所以如果有漏洞或者更好的思路的话,欢迎dalao们提出意见或建议~
1、自定指令
首先,指令的格式是 xxx (+、-、*、/) yyy ,xxx代表的是一个信号,yyy代表的是另一个信号;例如 sin*ang(表示正弦信号×三角波);当然算出的结果仅仅是形状正确,理论上经过放大之后就是得到的正确信号(只用乘上或是除以一个固定比例值即可),当然,前提是信号不失真。
在这里,我定义了几个信号所表示的符号(指令):
1、sin (正弦信号)
2、ang (三角波)
3、saw (锯齿波)
4、squ (方波)
5、cir (半圆波)
6、non (什么也没有)
2、串口的一些操作
这一次某些地方用了寄存器的操作(主要是用寄存器心里踏实)
1、首先是中断,在进入while(1)循环前,一定要先调用这个,目的是开启 读数据寄存器非空 中断
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
3、中断服务程序:
(用cubeMX的话,照网上的说法其实这样写并不标准,但是其实是可以用的,目前没有出现任何问题)
read_flag=1;
作为接受之后的一个标志位,当然在这里特地设定的为7个(标准的做法是判断接受非空)
现在是需要每个指令+回车才可以
<div class="blockcode"><blockquote>void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
uart_read_dat=USART2->DR&0XFF;
uart_read_buf[list]=uart_read_dat;
list++;
if(uart_read_dat=='\n'){
list=0;
read_flag=1;
}
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE);
//printf("%d\n",list);
/* USER CODE END USART2_IRQn 1 */
}
4、指令的判断
其实就是循环对每个字符进行判断,逻辑比较简单
//start_point 是开始数组下标 只对比3个字符
unsigned char std_str_con(unsigned char *str,unsigned char start_point){
unsigned char i,j,count,out_dat;
count=0;
out_dat=0;
for(i=0;i<7;i++){
count=0;
for(j=start_point;j<3+start_point;j++){
if(str[j]==signal_class[i][j-start_point])count++;
}
if(count==3){
out_dat=i+1;
break;
}
}
return out_dat;
}
5、运算
unsigned char scan_str_con(unsigned char *str){
unsigned char first_num,second_num,return_num;
first_num=std_str_con(str,0);
second_num=std_str_con(str,4);
if(first_num>0&&first_num<8){
switch(str[3]){
case '+':return_num=first_num+second_num;break;
case '-':return_num=first_num-second_num;break;
case '*':return_num=first_num*second_num;break;
case '/':return_num=first_num/second_num;break;
default :return_num=0;break;
}
}else{
return_num=0;
}
return return_num;
}
6、主函数里的循环
while (1)
{
if(read_flag) //接收数据完毕
{
read_flag=0;
read_command=scan_str_con(uart_read_buf);
if(read_command==0){ //非法指令
printf("error command!\n");
}else{ //合法指令
for(i=0;i<7;i++){
printf("%c",uart_read_buf[i]);
}
printf("结果是:%d\n",read_command);
}
printf("\n");
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
7、执行效果
这里把每个指令字符串定义为了一个数进行运算,其实放到信号上也是同样的道理,只不过是信号代替了数值。如果指令正确,串口会返回一个计算过的数值,如果错误则显示“error”。
|