由主机和从机组成
主机有由STM32F103RCT6单片机核心板+红外发送块+按键组成
从机有由STM32F103RCT6单片机核心板+红外接收模块+四针OLED 屏幕
1、按键1按下,主机单片机内部存储的:一个模拟信号和数字信号。通过红外模块发送给从机,从机进行数据处理后,显示在液晶上
有没有啥例程啊
引用new bing部分回答作答:
以下是一个基本的C语言程序示例,用于实现您描述的功能:
主机程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32f10x.h"
#include "ir.h"
#define IR_PIN GPIO_Pin_9
#define IR_PORT GPIOB
#define IR_GPIO_CLK RCC_APB2Periph_GPIOB
#define BUTTON_PIN GPIO_Pin_10
#define BUTTON_PORT GPIOB
#define BUTTON_GPIO_CLK RCC_APB2Periph_GPIOB
uint8_t data[4]; // 存储发送给从机的数据
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(IR_GPIO_CLK | BUTTON_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = IR_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(IR_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = BUTTON_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
GPIO_Init(BUTTON_PORT, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource10);
EXTI_InitStructure.EXTI_Line = EXTI_Line10;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
IR_Init(TIM2);
while (1) {
if (GPIO_ReadInputDataBit(BUTTON_PORT, BUTTON_PIN) == RESET) {
IR_SendData(data, sizeof(data));
}
}
}
void EXTI15_10_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line10) != RESET) {
EXTI_ClearITPendingBit(EXTI_Line10);
// 处理按键按下的逻辑
// 将数据存储到 data 数组中
}
}
从机程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stm32f10x.h"
#include "ir.h"
#include "oled.h"
#define IR_PIN GPIO_Pin_8
#define IR_PORT GPIOB
#define IR_GPIO_CLK RCC_APB2Periph_GPIOB
#define OLED_IIC_SCL_PIN GPIO_Pin_10
#define OLED_IIC_SCL_PORT GPIOB
#define OLED_IIC_SCL_CLK RCC_APB2Periph_GPIOB
#define OLED_IIC_SDA_PIN GPIO_Pin_11
#define OLED_IIC_SDA_PORT GPIOB
#define OLED_IIC_SDA_CLK RCC_APB2Periph_GPIOB
uint8_t data[4]; // 存储接收到的数据
int main(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(OLED_IIC_SCL_CLK | OLED_IIC_SDA_CLK, ENABLE);
RCC_APB2PeriphClockCmd(IR_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = OLED_IIC_SCL_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(OLED_IIC_SCL_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = OLED_IIC_SDA_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(OLED_IIC_SDA_PORT, &GPIO_InitStructure);
OLED_Init();
while (1) {
if (IR_RecvData(data, sizeof(data))) {
// 处理接收到的数据
OLED_Clear();
OLED_ShowString(0, 0, "Data Received:");
OLED_ShowNum(0, 2, data[0], 3, 16);
OLED_ShowNum(32, 2, data[1], 3, 16);
OLED_ShowNum(64, 2, data[2], 3, 16);
OLED_ShowNum(96, 2, data[3], 3, 16);
}
}
}
此示例程序仅供参考,并且可能需要根据您的实际硬件配置和需求进行修改。此外,还需要包含红外收发模块和 OLED 屏幕的库文件,并根据需要修改初始化参数。
1 .代码编写
在野火提供的示例代码中,打开一个只包含固件库的空项目。向工程中添加相关代码,添加代码的具体内容请参考下面链接:
https://blog.csdn.net/hhhhhh277523/article/details/111397514
具体的工程项目包下载 链接:https://pan.baidu.com/s/1-uYzWATsvkOYRmazolQAzA
提取码:4xva
2 .部分代码分析
AHT20 芯片的初始化
//初始化AHT20
void AHT20_Init(void)
{
IIC_Init();
IIC_Start();
IIC_Send_Byte(0x70);
IIC_Wait_Ack();
IIC_Send_Byte(0xa8);//0xA8进入NOR工作模式
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(10);//延时10ms左右
IIC_Start();
IIC_Send_Byte(0x70);
IIC_Wait_Ack();
IIC_Send_Byte(0xbe);//0xBE初始化命令,AHT20的初始化命令是0xBE, AHT10的初始化命令是0xE1
IIC_Wait_Ack();
IIC_Send_Byte(0x08);//相关寄存器bit[3]置1,为校准输出
IIC_Wait_Ack();
IIC_Send_Byte(0x00);
IIC_Wait_Ack();
IIC_Stop();
delay_ms(10);//延时10ms左右
}
AHT20 芯片读取并保存数据
//没有CRC校验,直接读取AHT20的温度和湿度数据
void AHT20_Read_CTdata(u32 *ct)
{
volatile u8 Byte_1th=0,Byte_2th=0,Byte_3th=0;
volatile u8 Byte_4th=0,Byte_5th=0,Byte_6th=0;
u32 RetuData = 0;
u16 cnt = 0,flag;
AHT20_SendAC();//向AHT20发送AC命令
delay_ms(80); //大约延时80ms
while(((AHT20_Read_Status()&0x80)==0x80))//直到状态bit[7]为0,表示为空闲状态,若为1,表示忙状态
{
delay_ms(1);
if(cnt++>=100) break;
}
IIC_Start();
IIC_Send_Byte(0x71);
flag=IIC_Wait_Ack();
Byte_1th = IIC_Read_Byte(flag);//状态字
Byte_2th = IIC_Read_Byte(flag);//湿度,发送ACK(继续发送)
Byte_3th = IIC_Read_Byte(flag);//湿度
Byte_4th = IIC_Read_Byte(flag);//湿度/温度
Byte_5th = IIC_Read_Byte(flag);//温度
Byte_6th = IIC_Read_Byte(!flag);//温度,发送NACK(停止发送)
IIC_Stop();
//保存得到的数据到RetuData中
RetuData = (RetuData|Byte_2th)<<8;
RetuData = (RetuData|Byte_3th)<<8;
RetuData = (RetuData|Byte_4th);
RetuData =RetuData >>4;
ct[0] = RetuData;//湿度
RetuData = 0;
RetuData = (RetuData|Byte_4th)<<8;
RetuData = (RetuData|Byte_5th)<<8;
RetuData = (RetuData|Byte_6th);
RetuData = RetuData&0x0fffff;
ct[1] =RetuData; //温度
}
main.c 函数
#include "led.h"
#include "usart.h"
#include "temhum.h"
int main(void)
{
u32 CT_data[2]={0};
volatile float hum=0,tem=0;
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
temphum_init(); //ATH20初始化
while(1)
{
AHT20_Read_CTdata(CT_data); //不经过CRC校验,直接读取AHT20的温度和湿度数据
hum = CT_data[0]*100*10/1024/1024; //计算得到湿度值(放大了10倍)
tem = CT_data[1]*200*10/1024/1024-500;//计算得到温度值(放大了10倍)
printf("湿度:%.1f%%\r\n",(hum/10));
printf("温度:%.1f度\r\n",(tem/10));
printf("\r\n");
//延时2s,LED闪烁提示串口发送状态
LED=0;
delay_ms(1000);
LED=1;
delay_ms(1000);
}
}
3 .编译调试后生成hex文件,然后烧录进STM32,具体烧录过程请参考:
https://blog.csdn.net/lengyuefeng212/article/details/104178386
4 .串口结果显示
打开串口助手,实验结果如下:
如图所示,用手握住传感器即可看到其温度得到了明显升高,环境湿度改变后同样湿度也有了变化。
以下内容引用CHATGPT、有用望采纳:
可以使用STM32 HAL库中提供的红外收发模块驱动来实现红外通信,同时使用OLED显示屏幕的驱动库来控制OLED屏幕显示。具体的实现思路可以分为以下几个步骤:
初始化主机和从机的单片机核心板和外设模块,包括红外发送块、红外接收模块和OLED屏幕。
在主机单片机内部存储一个模拟信号和数字信号,同时设置一个按键来触发数据发送。
当按键按下时,主机单片机通过红外发送块将数据发送给从机单片机。从机单片机接收到数据后进行数据处理,然后将处理结果显示在OLED屏幕上。
主机单片机可以通过红外接收模块接收从机单片机发送的数据,实现双向通信。
以下是一个可能的C语言实现示例:
#include "stm32f1xx_hal.h"
#include "oled.h"
#include "ir.h"
#define IR_SEND_PIN GPIO_PIN_5
#define IR_SEND_PORT GPIOB
#define IR_RECV_PIN GPIO_PIN_6
#define IR_RECV_PORT GPIOB
#define KEY_PIN GPIO_PIN_0
#define KEY_PORT GPIOA
uint16_t analog_data = 0;
uint8_t digital_data = 0;
uint8_t recv_data[4] = {0};
void main(void)
{
HAL_Init();
OLED_Init();
IR_Init(IR_RECV_PIN, IR_RECV_PORT, IR_SEND_PIN, IR_SEND_PORT);
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = KEY_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY_PORT, &GPIO_InitStruct);
while (1)
{
if (HAL_GPIO_ReadPin(KEY_PORT, KEY_PIN) == GPIO_PIN_RESET)
{
analog_data = 1023; // 读取模拟信号
digital_data = 0xFF; // 读取数字信号
IR_SendData(analog_data, digital_data); // 发送数据
HAL_Delay(100);
IR_RecvData(recv_data, 4); // 接收数据
OLED_Clear();
OLED_ShowString(0, 0, "Analog data:");
OLED_ShowNum(0, 2, analog_data, 4, 12);
OLED_ShowString(0, 4, "Digital data:");
OLED_ShowNum(0, 6, digital_data, 2, 12);
OLED_ShowString(0, 8, "Recv data:");
OLED_ShowString(0, 10, (char*)recv_data);
}
}
}
在以上代码中,我们使用了STM32 HAL库中提供的GPIO、延时、红外收发模块驱动和OLED屏幕驱动库来实现红外通信和OLED屏幕显示。在主函数中,我们初始化了各个外设模块,并在循环中检测按键是否按下。当按键按下时,我们读取模拟信号和数字信号,并使用红外发送模块将数据发送给从机单片机。然后我们延时一段时间,等待从机单片机处理数据并发送回来,然后使用红外接收模块接收数据,并在OLED屏幕上显示处理结果。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题涉及的知识点比较多,需要分步骤进行解答。
红外通信需要用到红外发送块和红外接收模块,这两个模块可以通过红外波长的匹配来进行数据的传输。具体的实现方法可以参考红外通信的相关资料或者使用现成的红外通信模块。
要实现主从机之间数据的传输,需要定义一套数据传输协议。具体的协议内容可以根据实际需要自行设计,但是一般包括数据的类型、数据的长度、校验位等信息。可以将这些信息打包成一个数据包进行传输。
从机接收到主机发送过来的数据包后,需要进行解包和数据处理。解包时需要根据协议内容进行拆包,得到原始的数据信息。然后根据数据的类型和长度进行相应的数据处理,并将处理好的数据显示在OLED屏幕上。
主机需要通过按键触发发送数据给从机。按键触发后,主机需要读取内部存储的模拟信号和数字信号,并将这些信息打包成数据包进行发送。
下面是一个简单的示例代码,仅供参考:
主机代码:
// 定义数据传输协议
typedef struct {
uint8_t type; // 数据类型
uint8_t length; // 数据长度
uint16_t data1; // 模拟信号
uint8_t data2; // 数字信号
uint8_t checksum; // 校验位
} DataPacket;
DataPacket packet;
void setup() {
// 初始化红外发送块
// 初始化按键
}
void loop() {
if (digitalRead(Button1) == LOW) {
// 读取模拟信号和数字信号
packet.type = 1;
packet.length = 4;
packet.data1 = analogRead(A0);
packet.data2 = digitalRead(Pin1);
// 计算校验位
packet.checksum = packet.type + packet.length + packet.data1 + packet.data2;
// 发送数据
infrared_Send(packet);
}
}
从机代码:
// 定义数据传输协议
typedef struct {
uint8_t type; // 数据类型
uint8_t length; // 数据长度
uint16_t data1; // 模拟信号
uint8_t data2; // 数字信号
uint8_t checksum; // 校验位
} DataPacket;
DataPacket packet;
void setup() {
// 初始化红外接收模块
// 初始化OLED屏幕
}
void loop() {
if (infrared_Available()) {
// 接收数据
infrared_Receive(&packet);
// 验证校验位
if (packet.type + packet.length + packet.data1 + packet.data2 == packet.checksum) {
// 进行数据处理并在OLED屏幕上显示
oled_Display(packet.data1, packet.data2);
}
}
}
如果我的回答解决了您的问题,请采纳!
引用chatGPT作答,这是一个涉及到STM32单片机和红外模块通信以及OLED屏幕显示的应用程序,需要涉及到多个模块和功能的代码,没有一个固定的例程可以直接使用。不过你可以通过以下步骤来实现这个应用程序:
1.确定通信协议和通信方式:根据你使用的红外模块的型号和从机的红外接收模块,选择一个合适的通信协议和通信方式,例如NEC红外协议和38KHz调制方式等。在主机和从机的单片机代码中,需要编写红外通信相关的代码,例如发送数据和接收数据的函数等。
2.实现数据处理:在从机的单片机代码中,需要编写数据处理的代码,将接收到的数据进行处理,例如解码数据、显示在OLED屏幕上等。具体的处理方式取决于你要传输的数据格式和内容,需要自行编写。
3.编写主机单片机按键处理代码:在主机单片机代码中,需要编写按键处理的代码,例如按键检测和处理函数等。当按键1被按下时,需要将模拟信号和数字信号发送给从机。
4.编写串口通信代码:在主机单片机代码中,需要编写串口通信的代码,将模拟信号和数字信号发送给从机。在从机单片机代码中,需要编写串口通信的代码,将接收到的数据传递给数据处理函数进行处理。
5.编写OLED屏幕显示代码:在从机单片机代码中,需要编写OLED屏幕显示的代码,将处理后的数据显示在屏幕上。具体的显示方式取决于你要显示的内容和显示器的型号,需要自行编写。
由于这是一个比较复杂的应用程序,需要涉及到多个模块和功能的代码,所以需要根据你具体的硬件环境和应用要求进行编写,不能直接使用现成的例程。如果你遇到了具体的问题,可以提出具体的问题,我们可以帮你解决。
您好,本着来提问就是能白嫖就白嫖的原则,我这又费点事把我的工程demo分享给你,供你参考,望你早日调通你的工程吧。
下面的代码是main.c中的代码
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM7_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
printf(" IR Remote testing... please press the controller!!!\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(receive_Flag == 1){
receive_Flag = 0;
printf("IR Received Code: %0.8x\r\n",receive_Code);
receive_Code = 0;
}
HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
HAL_Delay(100);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
实验现象:
提供两个历程给你参考:
https://download.csdn.net/download/weixin_44317448/87696595
https://download.csdn.net/download/weixin_44317448/87654794