安徽网新科技怎么建设网站,公司网站及微信公众号建设意义,用凡科做的网站要钱吗,高清电影下载矩阵键盘工作原理
矩阵键盘由多个独立按键组成#xff0c;按键的一端接地#xff0c;一端接MCU的GPIO。当按键没有被按下时#xff0c;电路其实是一个断路#xff0c;将单片机该引脚设置成输入上拉状态#xff0c;读到的电平为高电平。当按下按键时#xff0c;引脚会被拉…矩阵键盘工作原理
矩阵键盘由多个独立按键组成按键的一端接地一端接MCU的GPIO。当按键没有被按下时电路其实是一个断路将单片机该引脚设置成输入上拉状态读到的电平为高电平。当按下按键时引脚会被拉低此时读到的电平为低电平说明按键已经被按下。 4*4的矩阵键盘通常采用逐行逐列进行扫描。先扫描第一行将该行输出高电平其他行输出低电平记为0xF71111 0111。然后开始扫描列控制列的引脚为输入引脚将其和0XF7相与如果哪一位为0那么就证明哪一个被按下。 其本质就是进行逐行扫描和逐列扫描然后判断是第几行的第几列个按键进而进行整体按键值得确定。
实验案例
随机按下矩阵键盘按键可以在TFTLCD屏上观察到相应的数值。
实验需要STM32核心板 和 4*4矩阵键盘电路原理图
其中KR-0对应单片机PC0KR-1对应PC1KR-2对应PC2KR-3对应PC3KC-0对应PC4KC-1对应PC5KC-2对应PC6KC-3对应PC7。 程序源码 首先要对矩阵键盘IO进行初始化定义好矩阵键盘的行和列。然后需要定义好矩阵键盘扫描函数用于判断键盘按键是否按下。矩阵键盘扫描函数如下。
u8 keyscan(void)
{ uint8_t LIE,HANG,k,i0;GPIO_Write(GPIOC, 0xF0); //D0-D3拉低,D4-D7拉高if((GPIO_ReadInputData(GPIOC)0xF0)!0xF0) //有按键按下{delay_ms(40); //去抖if((GPIO_ReadInputData(GPIOC)0xF0)!0xF0) //再次判断是否按下{LIEGPIO_ReadInputData(GPIOC); //读取按键按下后得到的代码HANGLIE; //将代码复制给行LIE~LIE; //将键码取反例如按下某个键得到0111 0000取反后得到1000 1111LIELIE0XF0; //得到列1000 11111111 0000得到1000 0000,得到列数for(i0;i4((HANG0xF0)!0xF0);i) //逐次将行拉高判断列数中原来变低的位是否变高{ //读到之前检测到为低的列变高则推出GPIO_Write(GPIOC, (HANG0xF0)|(0x01i)); //进行行扫描逐次将行口线拉高列保持为按下的状态HANGGPIO_ReadInputData(GPIOC); //读取IO口用以判断是否扫描到行坐标 }HANG0x0F; //将航值取出kLIE|HANG; //行列相加则得到键码GPIO_Write(GPIOC, 0xF0); //D0-D3拉低,D4-D7拉高,此处用来将行状态初始化为未按下时的状态while((GPIO_ReadInputData(GPIOC)0xF0)!0xF0) //判释放{delay_ms(40); //后延消抖。时间需要长一点}return k; //返回键码}} return (0); //无键按下返回0
}在主函数中实现功能进行函数调用。为方便验证按键是否按下并方便观察使其在屏幕中显示主函数中包含显示功能。主函数如下。
int main(void){ u8 x0;u8 lcd_id[12]; //存放LCD ID字符串u8 key_value;u8 buf[20]; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //LED端口初始化LCD_Init();KEY_Init(); //矩阵按键初始化 sprintf((char*)lcd_id,LCD ID:%04X,lcddev.id);//将LCD ID打印到lcd_id数组。 POINT_COLORRED; LCD_ShowString(30,40,210,24,24,STM32 ^_^); LCD_ShowString(30,70,200,16,16,TFTLCD TEST);LCD_ShowString(30,90,200,16,16,STM32F103ZET6);LCD_ShowString(30,110,200,16,16,lcd_id); //显示LCD IDLCD_ShowString(30,130,200,12,12,2020/5/4);while(1) { key_value keyscan();if(key_value 0){ LCD_ShowNum(30,170,key_value,4,12);}}
}实验现象 矩阵键盘从左上角到右下角显示的数值依次为1~16。
红外对管测速原理
红外对管实质上是一种光电转换器件由发射管和接收管组成。发射管发出的光束经过聚焦后照射到被测物体上。接收管则负责接反射回来的光束将光信号转换为电信号产生光电效应。转换的这个电信号的大小取决于接收到的光强度。 为了能够准确地检测物体的移动速度需要对接收管产生的电信号进行适当的处理。常见的信号处理电路包括放大器、滤波器、比较器等。放大器用于放大微弱的电信号滤波器用于消除噪声比较器用于将信号转换为数字信号。
实验案例
在实验中我们采用定时器中断实现红外对管的测速。
实验需要STM32核心板直流电机蜂鸣器光电对管电路原理图
LM393会将光电对管输出的电压变化转换为高低电平方波并通过IRS-IO输出到单片机其中滑动电阻用于控制光电对管的灵敏度。 光电对管的输出口会通过选择开关与单片机的PB13接口相连。 程序源码 1、中断函数和中断服务程序
void EXTIX_Init(void)
{EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;INFRARED_Init();RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟//PB13 中断线以及中断初始化配置 下降沿触发 PB13 //红外对管对应PB13GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource13); EXTI_InitStructure.EXTI_LineEXTI_Line13;EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_LineCmd ENABLE;EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Rising; // 下降沿EXTI_Init(EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel EXTI15_10_IRQn; //使能红外对管所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0x02; //抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority 0x03; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; //使能外部中断通道NVIC_Init(NVIC_InitStructure);
}
//外部中断13服务程序
void EXTI15_10_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line13)SET){count ; BEEP!BEEP; EXTI_ClearITPendingBit(EXTI_Line13); //清除LINE13 上的中断标志位 }
}2、主函数
int main(void){ delay_init(); //延时函数初始化¯ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /设置NVIC中断分组22抢占优先级2响应优先级uart_init(115200); //´串口初始化为115200DCMOTOR_Init(); //直流电机初始化 LCD_Init();POINT_COLORRED;INFRARED_Init(); //初始化红外对管的硬件接口DCMOTOR1 1; //启动直流电机LED_Init(); //LED初始化 LCD_ShowString(30,40,210,24,24,STM32 ^_^); LCD_ShowString(30,70,200,16,16,TFTLCD TEST);LCD_ShowString(30,90,200,16,16,STM32F103ZET6);LCD_ShowString(30,130,200,12,12,2020/5/4); LCD_ShowString(30,170,200,16,16,COUNT:); TIM3_Int_Init(4999,7199);//10Khz的技术频率技术到5000为500msEXTIX_Init(); //外部中断初始化¯count 0 ;timer_count 0 ;while(1){ if(timer_count 0){ count_temp count;count 0;timer_count 0; LCD_ShowNum(78,170,count_temp,4,16); //当前显示的为1s内转的格数 count_temp 0 ;} }}实验现象 下载成功后复位两个直流电机带动码盘转动。通过红外对管检测码盘计数并在液晶屏上显示0.5秒内码盘转动格子数。