本帖最后由 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”。 
 
 
 
 
 
 
 
 
  |