OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3658|回复: 5

新手试图通过串口通信在电脑上输入数字来控制板子上灯泡的发亮时间

[复制链接]

1

主题

5

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2022-1-2
在线时间
8 小时
发表于 2022-3-13 20:19:53 | 显示全部楼层 |阅读模式
1金钱
main.c程序如下,我在PB0处连接了灯泡,希望达到的效果是键盘处输入一个数字来控制灯泡的发亮时间,并且电脑端收到一模一样的数字。
但是导入芯片跑起来,打开xcom串口助手之后的实验现象是
①不管发送过去的是三位四位,但串口收回的数字只有前两位,且两位之间间隔一段时间
eg:发送0000 ,现象:(串口显示0,同时灯泡亮)→(延迟一下)→(串口显示00)(灯泡灭)。
②无论我输入数字多少,灯泡每次发亮时间都差不多一样长,将近1秒。

#include "stm32f10x.h"
#include "led.h"
#include "delay.h"

void My_USART1_Init(){
        GPIO_InitTypeDef GPIO_Initstruct;
        USART_InitTypeDef USART_Initstruct;
        NVIC_InitTypeDef NVIC_InitStruct;
       
        //step1使能gpio时钟,使能usart时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
       
        //step2 gpio初始化
        //根据中文参考手册P110,将PA9,PA10设为复用推挽与浮空输入
        GPIO_Initstruct.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_Initstruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Initstruct.GPIO_Pin=GPIO_Pin_9;
        GPIO_Init(GPIOA,&GPIO_Initstruct);
       
        GPIO_Initstruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_Initstruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Initstruct.GPIO_Pin=GPIO_Pin_10;
        GPIO_Init(GPIOA,&GPIO_Initstruct);
       
        //step3 usart初始化
        USART_Initstruct.USART_BaudRate=115200;           
  USART_Initstruct.USART_WordLength=USART_WordLength_8b;         
  USART_Initstruct.USART_StopBits=USART_StopBits_1;            
  USART_Initstruct.USART_Parity=USART_Parity_No;              
  USART_Initstruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;    //可以同时使能两个功能:收与发            
  USART_Initstruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
        USART_Init(USART1,&USART_Initstruct);
       
        //step4 使能USART_cmd串口服务函数
        USART_Cmd(USART1,ENABLE);
       
        //step5 使能:串口来数据中断
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
        //配置这一中断
        //NVIC:Nested vectored interrupt controller
        //IRQ:interrupt quest中断请求
        NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2;//抢断优先级:level-2
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//抢断子优先级,随意设置的1
        NVIC_Init(&NVIC_InitStruct);
       
}
int main(void)
{       
         LED_Init();
         My_USART1_Init();
         delay_init();
         GPIO_SetBits(GPIOB,GPIO_Pin_0);
         delay_ms(500);
         GPIO_ResetBits(GPIOB,GPIO_Pin_0);
         while(1);

}
void USART1_IRQHandler(void)//中断服务函数
        {
          u8 Res;
                int time;
        if(USART_GetITStatus(USART1, USART_IT_RXNE))  
                {
                  Res=USART_ReceiveData(USART1);
                        USART_SendData(USART1,Res);       
                        GPIO_SetBits(GPIOB,GPIO_Pin_0);
                        time = 1000*Res;
                        delay_ms(time);
      GPIO_ResetBits(GPIOB,GPIO_Pin_0);                       
                }
        }



求助,求助,如何达到我想要的实验效果!!



最佳答案

查看完整内容[请看2#楼]

因为串口助手发送的数据一般好像是ASC码,而你这里的res一次只能收8位,所以你可以弄一个数组能够把你在电脑那边发送的数据全部接收完 ,然后再发送。 你可以改成这样试试 u8 sta [10] if(USART_GetITStatus(USART1, USART_IT_RXNE)!=Reset) { Res=USART_ReceiveData(USART1); sta=res; USART_clear_flag(USART1, USART_IT_RXNE);//我也忘了那个清中断函数啥样,你找找} i++;if(i>=10)i=0; USART_SendData(USART ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

74

帖子

0

精华

初级会员

Rank: 2

积分
188
金钱
188
注册时间
2021-12-22
在线时间
34 小时
发表于 2022-3-13 20:19:54 | 显示全部楼层
本帖最后由 13169175513 于 2022-3-14 16:21 编辑

因为串口助手发送的数据一般好像是ASC码,而你这里的res一次只能收8位,所以你可以弄一个数组能够把你在电脑那边发送的数据全部接收完 ,然后再发送。
你可以改成这样试试
u8 sta [10]
if(USART_GetITStatus(USART1, USART_IT_RXNE)!=Reset)
{
  Res=USART_ReceiveData(USART1);
  sta=res;
  USART_clear_flag(USART1, USART_IT_RXNE);//我也忘了那个清中断函数啥样,你找找
}
  i++;if(i>=10)i=0;  
USART_SendData(USART1,sta);   
  GPIO_SetBits(GPIOB,GPIO_Pin_0);
  time = 1000*Res;
  delay_ms(time);
  GPIO_ResetBits(GPIOB,GPIO_Pin_0);   





回复

使用道具 举报

11

主题

2131

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4734
金钱
4734
注册时间
2015-1-10
在线时间
591 小时
发表于 2022-3-14 13:12:46 | 显示全部楼层
这个代码确实很新手,第一,中断服务里面不要有类似延时的长时间阻塞代码;第二,用定时器控制GPIO实现灯的开关;第三,串口值控制开关时用的是二进制码还是ASC码?
回复

使用道具 举报

0

主题

668

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1926
金钱
1926
注册时间
2021-8-13
在线时间
262 小时
发表于 2022-3-14 13:13:40 | 显示全部楼层
帮顶   
回复

使用道具 举报

2

主题

141

帖子

0

精华

高级会员

Rank: 4

积分
679
金钱
679
注册时间
2020-11-21
在线时间
67 小时
发表于 2022-3-14 16:17:07 | 显示全部楼层
程序的流程还需要捋一捋,最简单就是 将延时时间设置为变量,然后在死循环中通过延时控制亮灭。然后串口接收到数据之后,直接修改延时时间的变量值就行。
回复

使用道具 举报

1

主题

5

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2022-1-2
在线时间
8 小时
 楼主| 发表于 2022-4-9 22:32:03 | 显示全部楼层
阿侑kevin 发表于 2022-3-14 13:12
这个代码确实很新手,第一,中断服务里面不要有类似延时的长时间阻塞代码;第二,用定时器控制GPIO实现灯的 ...

好的,,,我不知道中断里面不能加延时类代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-27 13:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表