stm32f103c8t6的NEC红外发送代码不用hal库
时间: 2023-06-19 12:10:31 浏览: 166
以下是使用STM32F103C8T6的NEC红外发送代码,不依赖HAL库:
```c
#include "stm32f10x.h"
#define IR_PIN GPIO_Pin_0
#define IR_PORT GPIOA
#define IR_GPIO_CLK RCC_APB2Periph_GPIOA
// 定义红外发送频率
#define IR_FREQ 38000
// 定义红外码的长度
#define IR_CODE_LEN 32
// 定义发送时序
#define IR_START_H 9000
#define IR_START_L 4500
#define IR_BIT_H 560
#define IR_BIT_0_L 560
#define IR_BIT_1_L 1690
// 定义红外发送状态
#define IR_IDLE 0
#define IR_SENDING 1
// 定义红外发送的缓冲区
uint32_t ir_code_buf[IR_CODE_LEN];
volatile uint32_t *ir_code = ir_code_buf;
volatile uint8_t ir_code_idx = 0;
volatile uint8_t ir_state = IR_IDLE;
// 红外发送初始化
void IR_Init(void) {
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(IR_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Pin = IR_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(IR_PORT, &GPIO_InitStructure);
}
// 发送红外码
void IR_Send(uint32_t code) {
// 将红外码转换为二进制并存储到缓冲区
uint8_t i;
for (i = 0; i < IR_CODE_LEN; i++) {
ir_code_buf[i] = code & 0x00000001;
code = code >> 1;
}
// 初始化发送状态
ir_state = IR_SENDING;
ir_code_idx = 0;
// 开始发送
TIM_Cmd(TIM2, ENABLE);
}
// TIM2中断处理函数
void TIM2_IRQHandler(void) {
static uint16_t bit_cnt = 0;
uint32_t bit_val = *(ir_code + ir_code_idx);
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
// 清除中断标志位
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
if (ir_state == IR_SENDING) {
// 发送开始码
if (ir_code_idx == 0) {
GPIO_SetBits(IR_PORT, IR_PIN);
TIM_SetAutoreload(TIM2, IR_START_H);
} else if (ir_code_idx == 1) {
GPIO_ResetBits(IR_PORT, IR_PIN);
TIM_SetAutoreload(TIM2, IR_START_L);
} else {
// 发送数据位
if (bit_val == 0) {
GPIO_SetBits(IR_PORT, IR_PIN);
TIM_SetAutoreload(TIM2, IR_BIT_H);
} else {
GPIO_SetBits(IR_PORT, IR_PIN);
TIM_SetAutoreload(TIM2, IR_BIT_1_L);
}
}
// 更新状态
ir_code_idx++;
if (ir_code_idx >= IR_CODE_LEN) {
ir_state = IR_IDLE;
TIM_Cmd(TIM2, DISABLE);
}
}
}
}
int main() {
// 初始化红外发送
IR_Init();
// 配置TIM2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;
TIM_TimeBaseInitStruct.TIM_Prescaler = (SystemCoreClock / IR_FREQ) - 1;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
// 中断优先级配置
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
while (1) {
// 发送红外码
IR_Send(0x12345678);
// 延时
for (volatile int i = 0; i < 100000; i++);
}
}
```
这段代码使用了STM32F103C8T6的定时器TIM2来生成红外发送时序,并且不依赖HAL库。在代码中,我们定义了红外发送的频率、红外码的长度、发送时序以及红外发送状态。在`IR_Init`函数中,我们初始化了GPIO口用于控制红外发射管,而在`IR_Send`函数中,我们将待发送的红外码转换为二进制并存储到缓冲区中,然后开启TIM2开始发送。
在TIM2的中断处理函数中,我们根据当前发送状态和发送位置,设置GPIO口输出电平和计数器重载值,以生成不同的红外发送时序。当发送完成时,我们将红外发送状态设置为IDLE,禁用TIM2计数器,等待下一次发送。
阅读全文