T4:双机通信
使用一块 stm32 开发版和一块 51 开发版实现两块板子之间的通讯
(1)使用 51单片机的一个按键,当按键按下时,stm32上的一个 LED 灯点亮,5s后自动熄灭
(2)51单片机连接一个超声波传感器,使用 LCD 屏幕显示距离,当距离小于 10cm时,51单 片机蜂鸣器鸣叫报警,stm32 上的 LED 灯自动点亮;当距离大于 10cm,蜂鸣器停止鸣叫报警,LED 自动熄灭。
(3)stm32上按键按下,51单片机蜂鸣器鸣叫报警时间增加。
没有思路 可以提供大致代码思路吗
stm32 +51单片机 双机通信
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
7条回答 默认 最新
关注让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
1. 使用51单片机按键,发送一个数据给stm32,stm32接收到数据后点亮LED灯,然后延时5秒,熄灭LED灯。 51单片机代码:#include<reg51.h> sbit key = P1^0; //按键连接在P1.0口 void delay(unsigned int t){ //延时函数 unsigned int i,j; for(i=0;i<t;i++){ for(j=0;j<125;j++); } } void send_data(){ //发送数据的函数 //使用串口通信发送数据给stm32 } void main(){ while(1){ if(key == 0){ //按键按下 send_data(); //发送数据 delay(500); //延时,避免按键抖动 while(key == 0); //等待按键松开 } } }stm32代码:
#include "stm32f10x.h" #define LED_PIN GPIO_Pin_0 //LED灯连接在GPIOA.0口 #define USART_RX_PIN GPIO_Pin_10 //USART1接收引脚连接在GPIOA.10口 #define USART_TX_PIN GPIO_Pin_9 //USART1发送引脚连接在GPIOA.9口 void LED_On(){ //点亮LED灯的函数 GPIO_WriteBit(GPIOA, LED_PIN, Bit_SET); } void LED_Off(){ //熄灭LED灯的函数 GPIO_WriteBit(GPIOA, LED_PIN, Bit_RESET); } void USART1_Init(){ //USART1初始化函数 USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //配置USART1引脚GPIO GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //配置USART1参数 USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } void USART1_SendData(char data){ //发送单个字节的函数 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, data); } void EXTI0_IRQHandler(void){ //外部中断0的中断服务函数 if(EXTI_GetITStatus(EXTI_Line0) != RESET){ //判断是否是外部中断0的触发 LED_On(); //点亮LED灯 USART1_SendData('A'); //发送数据给51单片机 EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位 } } void delay_ms(uint32_t ms){ //毫秒级延时函数 SysTick->LOAD = 9 * ms; //计数器重载值 SysTick->VAL = 0; //清空计数器 SysTick->CTRL |= (1 << 0); //开启计数器 while((SysTick->CTRL & (1 << 16)) == 0); //等待计数器计满 } void SysTick_Init(){ //SysTick初始化函数 SysTick->CTRL = 0; //关闭计数器 SysTick->LOAD = 0xFFFFFFFF; //设置重载值 SysTick->VAL = 0; //清空计数器 SysTick->CTRL |= (1 << 2); //选择外部时钟源 } int main(void){ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; USART1_Init(); //USART1初始化 //配置LED灯引脚GPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //配置PA0为中断口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //配置为下降沿触发外部中断 EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //配置外部中断0对应的NVIC NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); SysTick_Init(); //初始化SysTick while(1){ delay_ms(1000); //等待1s LED_Off(); //熄灭LED灯 } }- 使用51单片机超声波传感器测量距离,并发送数据给stm32,stm32接收到数据后判断距离是否小于10cm,如果小于10cm,点亮LED灯,蜂鸣器鸣叫报警;如果大于等于10cm,熄灭LED灯,蜂鸣器停止鸣叫报警。 51单片机代码:
#include<reg51.h> sbit trig = P1^0; //超声波测距模块的trig引脚连接在P1.0口 sbit echo = P1^1; //超声波测距模块的echo引脚连接在P1.1口 sbit buzzer = P2^0; //蜂鸣器连接在P2.0口 unsigned int distance; //保存测量到的距离 void delay_us(unsigned int t){ //微秒级延时函数 unsigned int i,j; for(i=0;i<t;i++){ for(j=0;j<10;j++); } } void delay_ms(unsigned int t){ //毫秒级延时函数 unsigned int i,j; for(i=0;i<t;i++){ for(j=0;j<125;j++); } } void send_data(){ //发送数据的函数 //使用串口通信发送数据给stm32 } void measure_distance(){ //测量距离的函数 unsigned int t; trig = 1; //触发一次脉冲 delay_us(10); trig = 0; while(echo == 0); //等待从超声波模块返回的脉冲 t = TH1 * 256 + TL1; distance = t / 58; //计算距离 } void main(){ while(1){ measure_distance(); //测量距离 send_data(); //发送数据 delay_ms(50); //延时,避免测量频率过高 //如果距离小于10cm,点亮LED灯,蜂鸣器鸣叫报警 if(distance < 10){ P1 = 0xFF; //点亮LED灯 buzzer = 1; //鸣叫蜂鸣器 } //如果距离大于等于10cm,熄灭LED灯,蜂鸣器停止鸣叫报警 else{ P1 = 0x00; //熄灭LED灯 buzzer = 0; //停止鸣叫蜂鸣器 } } }stm32代码: 和上一个问题的stm32代码相同。 3. stm32上的按键按下时,发送一个数据给51单片机,51单片机收到数据后将报警时间增加。我们可以在第二题的51单片机代码中加入一个变量,用来保存报警时间,每次收到stm32发送的数据时,将变量加上一个固定的值即可。 修改后的51单片机代码:
#include<reg51.h> sbit trig = P1^0; //超声波测距模块的trig引脚连接在P1.0口 sbit echo = P1^1; //超声波测距模块的echo引脚连接在P1.1口 sbit buzzer = P2^0; //蜂鸣器连接在P2.0口 unsigned int distance; //保存测量到的距离 unsigned int alarm_time = 5000; //报警时间,初始化为5s void delay_us(unsigned int t){ //微秒级延时函数 unsigned int i,j; for(i=0;i<t;i++){ for(j=0;j<10;j++); } } void delay_ms(unsigned int t){ //毫秒级延时函数 unsigned int i,j; for(i=0;i<t;i++){ for(j=0;j<125;j++); } } void send_data(){ //发送数据的函数 //使用串口通信发送数据给stm32 } void measure_distance(){ //测量距离的函数 unsigned int t; trig = 1; //触发一次脉冲 delay_us(10); trig = 0; while(echo == 0); //等待从超声波模块返回的脉冲 t = TH1 * 256 + TL1; distance = t / 58; //计算距离 } void main(){ while(1){ measure_distance(); //测量距离 send_data(); //发送数据 delay_ms(50); //延时,避免测量频率过高 //如果距离小于10cm,点亮LED灯,蜂鸣器鸣叫报警 if(distance < 10){ P1 = 0xFF; //点亮LED灯 buzzer = 1; //鸣叫蜂鸣器 delay_ms(alarm_time); //报警时间 } //如果距离大于等于10cm,熄灭LED灯,蜂鸣器停止鸣叫报警 else{ P1 = 0x00; //熄灭LED灯 buzzer = 0; //停止鸣叫蜂鸣器 } } }stm32代码:
#include "stm32f10x.h" #define LED_PIN GPIO_Pin_0 //LED灯连接在GPIOA.0口 #define USART_RX_PIN GPIO_Pin_10 //USART1接收引脚连接在GPIOA.10口 #define USART_TX_PIN GPIO_Pin_9 //USART1发送引脚连接在GPIOA.9口 void LED_On(){ //点亮LED灯的函数 GPIO_WriteBit(GPIOA, LED_PIN, Bit_SET); } void LED_Off(){ //熄灭LED灯的函数 GPIO_WriteBit(GPIOA, LED_PIN, Bit_RESET); } void USART1_Init(){ //USART1初始化函数 USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); //配置USART1引脚GPIO GPIO_InitStructure.GPIO_Pin = USART_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //配置USART1参数 USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); } void USART1_SendData(char data){ //发送单个字节的函数 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, data); } void EXTI0_IRQHandler(void){ //外部中断0的中断服务函数 if(EXTI_GetITStatus(EXTI_Line0) != RESET){ //判断是否是外部中断0的触发 LED_On(); //点亮LED灯 USART1_SendData('A'); //发送数据给51单片机 EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志位 } } void delay_ms(uint32_t ms){ //毫秒级延时函数 SysTick->LOAD = 9 * ms; //计数器重载值 SysTick->VAL = 0; //清空计数器 SysTick->CTRL |= (1 << 0); //开启计数器 while((SysTick->CTRL & (1 << 16)) == 0); //等待计数器计满 } void SysTick_Init(){ //SysTick初始化函数 SysTick->CTRL = 0; //关闭计数器 SysTick->LOAD = 0xFFFFFFFF; //设置重载值 SysTick->VAL = 0; //清空计数器 SysTick->CTRL |= (1 << 2); //选择外部时钟源 } void alarm_time_increase(){ //报警时间增加函数 //发送数据给51单片机,让其将报警时间加上一个固定的值 } int main(void){ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; USART1_Init(); //USART1初始化 //配置LED灯引脚GPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = LED_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //配置PA0为中断口 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); //配置为下降沿触发外部中断 EXTI_InitStructure.EXTI_Line = EXTI_Line0; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //配置外部中断0对应的NVIC NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); SysTick_Init(); //初始化SysTick while(1){ delay_ms(1000); //等待本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报