510
个编辑
更改
→硬件设计
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 硬件设计 ===
''<span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span><span class="tlid-translation-gender-indicator translation-gender-indicator"></span>''
=== 实验准备 ===
# 使用miniUSB线及10pin排线,通过Jlink仿真器连接PC端和开发板。
# 使用miniUSB线,连接PC与开发板USB接口。
# 将SW1拨到DBG端,SW2拨到MCU。将SW1拨到USB端,SW2拨到MCU。# 使用Keil打开基础实验 0910-红外线接收实验工程。串口打印实验工程。# 使用Xshell打开Jlink虚拟出的COM口使用Xshell打开miniUSB虚拟出的COM口
# 下载程序,并完成功能测试。
=== 实验验证 ===
=== 源码详解 ===
此文件位于“09-红外线接收实验\Inc”路径中,主要用途是选择使能此例程使用到的库文件。
// 使能的宏
#define HAL_MODULE_ENABLED // 芯片
#define HAL_GPIO_MODULE_ENABLED // GPIO
#define HAL_DMA_MODULE_ENABLED // DMA
#define HAL_UART_MODULE_ENABLED // UART
</syntaxhighlight>
main函数,我们的例程由此处开始执行,首先调用HAL_Init()函数初始化我们的模块,接着调用SystemClock_Config()函数初始化此例程用到的时钟,具体有哪些时钟被初始化,在gyu_util.c部分有详细说明。
在while()循环中,我们轮询遥控器的按键信息,一旦有遥控器按下,则在LCD的对应位置,打印按键的信息。循环中,我们每隔100ms通过格式化输出"TimeCount = xx:xx:xx"。
<syntaxhighlight lang="c++" line="1" start="34">
int main(void)
{
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
// 重置所有外设、flash界面以及系统时钟
// 配置系统时钟(包含振荡器、系统时钟、总线时钟等等)
SystemClock_Config();
//
while(1)
{
{
}
}
</syntaxhighlight>
==== gyu_irc gyu_usartc ====
初始化定时器TIM3,首先配置TIM3的时钟为1MHz(也就是1us),我们设置它向上自动装载,并且设置自动装载值为10000,通过计算可以知道装满一次需要10ms。
最后使能TIM3的中断,并且开始捕获TIM3的通道1(也就是PC6引脚)。
<syntaxhighlight lang="c++" line="1" start="5937">void MX_TIM3_InitMX_USART1_UART_Init(void)
{
// 初始化TIM3输入捕获参数 TIM_IC_InitTypeDef sConfigIC; // 定义输入捕获结构体(IC:Input capture) sConfigIC.ICPolarity = TIM_ICPOLARITY_BOTHEDGE; // 上升沿下降沿都捕获 sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; // 配置为TI1 sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; // 不分频 sConfigIC.ICFilter = 0x03; // IC1F=0011 8个定时器时钟周期滤波 // 初始化TIM3 CH1通道,出错则进入错误处理函数串口初始化 if (HAL_TIM_IC_ConfigChannelHAL_UART_Init(&htim3, &sConfigIC, TIM_CHANNEL_1huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__); // 如果初始化失败,进入错误处理任务
}
}
</syntaxhighlight>使能GPIOC以及TIM3的时钟,并且配置PC6为TIM3的通道1。<syntaxhighlight lang="c++" line="1" start="9667">void HAL_TIM_IC_MspInitHAL_UART_MspInit(TIM_HandleTypeDef UART_HandleTypeDef*htimuartHandle)
{
}
</syntaxhighlight>定时器周期中断回调函数,TIM3的自动装载值装满一次,进入一次此回调(本工程配置的参数是10ms进入一次)。
如果是接收到引导码之后,第一次进入此函数,那么我们使能记录遥控器按键值的标志位,也就是代表接收到了一次NEC数据(不管数据对错)。
如果进入的次数少于11次,则继续增加计数,当计数值等于11时(也就是从接收到引导码已经过去至少110ms时),我们认为一次NEC的数据获取已经完成,此时清除周期回调的计数值,并且删除引导码标志位(下次再进到这个函数时,只有新的引导码数据到来,才会进行新的数据处理)。<syntaxhighlight lang="c++" line="1" start="12299">void HAL_TIM_PeriodElapsedCallback#define PUTCHAR_PROTOTYPE int fputc(TIM_HandleTypeDef int ch, FILE *htimf){ if(htim->Instance == TIM3) { if(irStatus & IR_STATUS_BootCode) // 如果接收到引导码 { irStatus &= ~IR_STATUS_Rising; // 删除上升沿标记(以防止本次出错,确保下次采集流程正确) if(tim3Cnt == 0) // 如果是第一次进入(计数为0) { irStatus |= IR_STATUS_BtnInfo; // 记录已经获取到IR按键信号(遥控器按键值) } if((tim3Cnt & 0X0F) < 11) // 进入回调少于11次 { tim3Cnt++; // 计数值自加 } else // 超过11次,代表一次采集超时(不论是否成功) { irStatus &= ~IR_STATUS_BootCode;// 删除引导码标记 tim3Cnt = 0; // 清除计数值 } } }}</syntaxhighlight>处理TIM3 CH1(PC6引脚)捕获的数据,这边要记得初始化中我们使能了上升沿下降沿都捕获数据。 当有边沿捕获到来,我们判断此时PC6引脚的电平。
{
// 判断是否为TIM3 CH1捕获产生的回调配置格式化输出到串口USART1 ifHAL_UART_Transmit((htim->Instance == TIM3) && (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)) { ifhuart1, (HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_6uint8_t *)) // 获取PC6引脚电平,如果是高电平,则代表是上升沿捕获 { __HAL_TIM_SET_COUNTER(&htim3ch, 0); // 清除TIM3定时器计数值 irStatus |= IR_STATUS_Rising; // 标记上升沿捕获 } else //如果是低电平,则代表是下降沿触发 { tim3Val = HAL_TIM_ReadCapturedValue(&htim31, TIM_CHANNEL_10xFFFF); // 读取TIM3 CH1定时器计数值 if(irStatus & IR_STATUS_Rising) // 存在上升沿标记,我们比较定时器计数值 { if(tim3Val > 260 && tim3Val < 860) // 高电平持续560us代表bit 0,范围560us±300us { irRecData <<= 1; // 左移一位 irRecData |= 0; // bit位赋值0 } else if(tim3Val > 1380 && tim3Val < 1980) // 高电平持续1680us代表bit 1,范围1680us±300us { irRecData <<= 1; // 左移一位 irRecData |= 1; // bit位赋值1 } else if(tim3Val > 2200 && tim3Val < 2800) // 高电平持续2500us代表本次按键结束,范围2500us±300us { irCnt++; // 按键次数新增1 tim3Cnt = 0; // 清除计数值 } else if(tim3Val > 4200 && tim3Val < 4800) // 高电平持续4500us代表新的按键,范围4500us±300us { irStatus |= IR_STATUS_BootCode; // 标记引导码 irCnt = 0return ch; // 有新的按键到来,清除按键计数 } } irStatus &= ~IR_STATUS_Rising; // 清除上升沿标记 } }
}
[[分类:NB-IOT]]
[[分类:NBDK-L4]]
[[分类:教程]]
__强显目录__