超声波测距实验
基本原理
超声波测距实验是STM32单片机通过控制HC-SR04超声波模块,使其发送超声波,遇到物体反射回超声波来实现距离测量,其原理就是在发射超声波到接收超声波会有一段时间,而超声波在空气中传播的速度为声速(340M/S),时间*声速就是超声波的往返距离,那么测量距离=(往返时间*声速)/2=超声波往返距离/2。
HC-SR04是怎样做到发送和接收超声波的呢?HC-SR04具有两个控制端口TRIG和ECHO,TRIG用于触发测距,ECHO用于检测是否有超声波信号返回。TRIG给至少10us的高电平信号(超过10us表示在正常工作),接着模块自动发送8个40khz的方波,自动检测是否有信号返回。有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。
实验原理图
程序代码
1、超声波发送与接收
c
void Wave_SRD_Strat(void)
{
GPIO_SetBits(GPIOB,Trig); //将Trig设置为高电平
delay_us(20); //持续大于10us触发,触发超声波模块工作
GPIO_ResetBits(GPIOB,Trig);
}
c
void EXTI9_5_IRQHandler(void)
{
delay_us(10);
if(EXTI_GetITStatus(EXTI_Line8)!=RESET)
{
TIM_SetCounter(TIM3,0);
TIM_Cmd(TIM3,ENABLE);
while(GPIO_ReadInputDataBit(GPIOF,Echo)); //等待低电平
TIM_Cmd(TIM3,DISABLE);
Distance=TIM_GetCounter(TIM3)*340/200.0;
if(Distance>0)
{
printf("Distance:%f cm\r\n",Distance);
}
EXTI_ClearITPendingBit(EXTI_Line8);
}
}
2、主函数
c
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
//EXTIX_Init(); //外部中断初始化
Timer_SRD_Init(5000,7199);
Wave_SRD_Init();
while(1)
{
Wave_SRD_Strat();
delay_ms(2000);
}
}
实验现象
运行程序后打开串口调试助手(注意选择波特率为115200),此时可以观察到串口实时输出超声波距离,可用障碍物遮挡不断实验,障碍物距离不同显示的数据不同。
IIC/EEPROM实验
单片机通过代码模拟IIC总线并对EEPROM芯片AT24C256进行读写,单片机会在0号地址写入字符串'STM32 IIC TEST',然后重新读取0号地址并通过TFTLCD屏显示出来。
AT24C256外围电路原理图
A0、A1:地址选择输入端。
SCL:串行时钟输入。上升沿将SDA上的数据写入存储器,下降沿从存储器读出数据送SDA上。
SDA:双向串行数据输入输出口。用于存储器与单片机之间的数据交换。
WP:写保护输入。此引脚与地相连时,允许写操作;与VCC相连时,所有的写存储器操作被禁止。如果不连,芯片内部下拉到地。
EEPROM 进入开始状态后,需要一个8位的地址字来选择芯片进行读写。设备地址字由5位0、1组成的命令字和两位地址选择位A1、A0和一位读/写操作位构成。对于 AT24C256,命令字为"10100",同一串行总线上可以连接4个设备,由地址线A1,A0加以区分。如只有一个AT24C256,A1,A0都取 0。最低位为1表示读操作,0表示写操作。
写操作有写页和写字节两种,读操作有当前地址读、随机读、读串三种方式。
程序代码
此处仅展示主函数。
c
int main(void)
{
u8 datatemp[SIZE];
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //初始化与LED连接的硬件接口
LCD_Init(); //初始化LCD
AT24CXX_Init(); //IIC初始化
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(30,50,200,16,16,"STM32");
LCD_ShowString(30,70,200,16,16,"IIC TEST");
LCD_ShowString(30,90,200,16,16,"STM32F103ZET6");
LCD_ShowString(30,110,200,16,16,"2015/1/15");
//LCD_ShowString(30,130,200,16,16,"KEY1:Write KEY0:Read"); //显示提示信息
while(AT24CXX_Check())//检测不到24c02
{
LCD_ShowString(30,150,200,16,16,"24C0256 Check Failed!");
printf("24C0256 Check Failed!");
delay_ms(500);
LCD_ShowString(30,150,200,16,16,"Please Check! ");
delay_ms(500);
LED0=!LED0;//DS0闪烁
}
LCD_ShowString(30,150,200,16,16,"24C0256 Ready!");
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_Fill(0,170,239,319,WHITE);//清除半屏
LCD_ShowString(30,170,200,16,16,"Start Write 24C0256....");
AT24CXX_Write(0,(u8*)TEXT_Buffer,SIZE); //写入
LCD_ShowString(30,170,200,16,16,"24C0256 Write Finished!");//提示传送完成
delay_ms(1800);
LCD_ShowString(30,170,200,16,16,"Start Read 24C0256.... ");
AT24CXX_Read(0,datatemp,SIZE); //读取
LCD_ShowString(30,170,200,16,16,"The Data Readed Is:");//提示传送完成
LCD_ShowString(30,190,200,16,16,datatemp);//显示读到的字符串
while(1);
}
实验现象
运行程序可以发现TFTLCD屏上显示EEPROM中0号地址保存的字符串"STM32 IIC TEST"。
触摸屏实验
触摸屏实验就是利用单片机制作一个绘图板功能,实现手、触摸笔写画功能。其主要采用电容式触摸屏。 电容式触摸屏主要分为两种:
1、 表面电容式电容触摸屏
表面电容式触摸屏技术是利用 ITO(铟锡氧化物,是一种透明的导电材料)导电膜,通过电场感应方式感测屏幕表面的触摸行为进行。但是表面电容式触摸屏有一些局限性,它只能识别一个手指或者一次触摸。
2、 投射式电容触摸屏
投射电容式触摸屏是传感器利用触摸屏电极发射出静电场线。一般用于投射电容传感技术的电容类型有两种:自我电容和交互电容。
自我电容又称绝对电容,是最广为采用的一种方法,自我电容通常是指扫描电极与地构成的电容。
交互电容又叫做跨越电容,它是在玻璃表面的横向和纵向的 ITO 电极的交叉处形成电容。交互电容的扫描方式就是扫描每个交叉处的电容变化,来判定触摸点的位置。
主函数
c
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
// KEY_Init();
tp_dev.init();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,50,200,16,16,"STM32");
LCD_ShowString(60,70,200,16,16,"TOUCH TEST");
LCD_ShowString(60,90,200,16,16,"STM32F103ZET6");
LCD_ShowString(60,110,200,16,16,"2020/1/15");
//LCD_ShowString(60,130,200,16,16,"Press KEY0 to Adjust");
// if(tp_dev.touchtype!=0XFF)LCD_ShowString(60,130,200,16,16,"Press KEY0 to Adjust");//电阻屏才显示
delay_ms(1500);
Load_Drow_Dialog();
if(tp_dev.touchtype&0X80)ctp_test(); //电容屏测试
else rtp_test(); //电阻屏测试
}