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