从PWM输出实验的工程开始,加入其他各种功能。
LCD屏幕显示:
一、hardware
其中timer是产生脉冲的。
二、hallib
FMC是一个接口,控制SDRAM和LCD
三、#include
#include “lcd.h” #include “sdram.h” 四、init()
SDRAM_Init(); //初始化SDRAM
LCD_Init(); //LCD初始化
这两个初始化是关键部分,首先SDRAM_Init(); 是SDRAM的底层驱动文件,LCD_Init();中会调用ltdc_init(),还会用到HAL_SDRAM_Init
USMART调试:
1.包含USMART文件夹以及它的path(不是hardware,么有hallib)
2.#include “usmart.h”
3.usmart_dev.init(108); //初始化USMART
4.usmart_config.c中,包含timer.h,在添加函数的地方添加TIM3_PWM_Init函数即可
5.打开串口调试助手直接发送TIM3_PWM_Init(999,107),同时可以随时更改舵机的转动角度。
RTC时钟:
1.hardware
rtc文件夹
2.hallib
stm32f7xx_hal_rtc.c
stm32f7xx_hal_rtc_ex.c
3.include
rtc.h
4.main
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;
u8 tbuf[40];
u8 t=0;
RTC_Init(); //初始化RTC
t++;
if((t%10)==0) //每100ms更新一次显示数据
{
HAL_RTC_GetTime(&RTC_Handler,&RTC_TimeStruct,RTC_FORMAT_BIN);
sprintf((char*)tbuf,“Time:%02d:%02d:%02d”,RTC_TimeStruct.Hours,RTC_TimeStruct.Minutes,RTC_TimeStruct.Seconds);
LCD_ShowString(30,140,210,16,16,tbuf);
HAL_RTC_GetDate(&RTC_Handler,&RTC_DateStruct,RTC_FORMAT_BIN);
sprintf((char*)tbuf,“Date:20%02d-%02d-%02d”,RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Date);
LCD_ShowString(30,160,210,16,16,tbuf);
sprintf((char*)tbuf,“Week:%d”,RTC_DateStruct.WeekDay);
LCD_ShowString(30,180,210,16,16,tbuf);
}
5.usmart
6.rtc.c中
中断处理回调函数:
#include “timer.h”
//RTC闹钟A中断处理回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
printf(“ALARM A!rn”);
TIM3_PWM_Init(1000*-1,108-1);
}
待机唤醒:
1.hardware
wkup
2.hallib
无
3.include
#include “wkup.h” 4.main
WKUP_Init(); //待机唤醒初始化
LCD_Init(); //初始化LCD
LCD_Init必须要在WKUP_Init之后,每次点击按键都会进入到main函数中,那么都会进入到WKUP_Init():
//WKUP_Init:
if(Check_WKUP()==0)
{
Sys_Enter_Standby();//不是开机,进入待机模式
}
//按键中断:
if(Check_WKUP())//关机
{
Sys_Enter_Standby();//进入待机模式
}
假如按下没有3秒,就直接Check_WKUP()==0进入待机;假如按下有3秒,跳过了Sys_Enter_Standby()可以正常开机,同时打开按键中断。如果开机后按下没有3秒,进入中断判断就不会进入Sys_Enter_Standby();如果开机后按下有3秒,直接进入待机。
TPAD:
1.hardware
tpad
2.hallib
无
3.include
#include “tpad.h”
4.main
TPAD_Init(8); //初始化触摸按键,以108/8=13.5Mhz频率计数
switch (TPAD_Scan(0)) //成功捕获到了一次上升沿(此函数执行时间至少15ms)
{
case 0:
LCD_LED(1); //开背光
LED1(1);
break;
case 1:
LCD_LED(0); //关背光
LED1(0);
break;
}
switch (TPAD_Scan(0)) 在while(1)里面循环。
5.tpad.c
u8 TPAD_Scan(u8 mode)
{
static u8 keyen=0; //0,可以开始检测;》0,还不能开始检测
static u8 res=0;
u8 sample=3; //默认采样次数为3次
u16 rval;
if(mode)
{
sample=6; //支持连按的时候,设置采样次数为6次
keyen=0; //支持连按
}
rval=TPAD_Get_MaxVal(sample);
if(rval》(tpad_default_val*4/3)&&rval《(10*tpad_default_val))//大于tpad_default_val+TPAD_GATE_VAL,且小于10倍tpad_default_val,则有效
{
if(keyen==0)res++; //大于tpad_default_val+TPAD_GATE_VAL,有
//printf(“r:%drn”,rval);
keyen=3; //至少要再过3次之后才能按键有效
}
if(keyen)keyen--;
res=res%2;
return res;
}
首先默认的是time2的通道1,gpio是pa5,然而pa5会和后面的ADC冲突,所以选择time2的通道3,gpio是pa2。
更改GPIO_PIN_2、TIM_CHANNEL_3即可,GPIO_AF1_TIM2不用管。
ADC:
1.hardware
ADC
2.hallib
adc.c以及adc_ex.c
3.main
#include“adc.h”
u16 adcx;float temp;
MY_ADC_Init(); //初始化ADC1通道
adcx=Get_Adc_Average(ADC_CHANNEL_5,20);//获取通道5的转换值,20次取平均
LCD_ShowxNum(134,130,adcx,4,16,0); //显示ADCC采样后的原始值
temp=(float)adcx*(3.3/4096); //获取计算后的带小数的实际电压值,比如3.1111
adcx=temp; //赋值整数部分给adcx变量,因为adcx为u16整形
LCD_ShowxNum(134,150,adcx,1,16,0); //显示电压值的整数部分,3.1111的话,这里就是显示3
temp-=adcx; //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
temp*=1000; //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
LCD_ShowxNum(150,150,temp,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
4.驱动文件
ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
GPIO_Initure.Pin=GPIO_PIN_5; //PA5
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
Get_Adc_Average(ADC_CHANNEL_5,20)是要得到通道5的值,所以要初始化PA5,假如是内部温度传感器,它是接的通道18,就不用管PA5,HAL_ADC_MspInit中只用使能ADC1时钟即可,Get_Temprate函数会得到通道18的电压值,temperate=(float)adcx*(3.3/4096);默认的参考电压都是0-3.3V,而12位的分辨率,通道里面得到的是数字,经过转换就可以得到对应的电压。
DAC:
1.hardware
DAC
2.hallib
dac.c以及dac_ex.c
3.main
#include “dac.h”
u16 dacval=0;u8 key;
DAC1_Init(); //初始化DAC1
LCD_ShowString(30,150,200,16,16,“DAC VAL:”);
LCD_ShowString(30,170,200,16,16,“DAC VOL:0.000V”);
LCD_ShowString(30,190,200,16,16,“ADC VOL:0.000V”);
key=KEY_Scan(0);
if(key==KEY2_PRES)
{
if(dacval《4000)dacval+=200;
HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dacval);//设置DAC值
}else if(key==KEY1_PRES)
{
if(dacval》200)dacval-=200;
else dacval=0;
HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dacval);//设置DAC值
}
if(t==10||key==KEY1_PRES||key==KEY2_PRES) //WKUP/KEY1按下了,或者定时时间到了
{
adcx=HAL_DAC_GetValue(&DAC1_Handler,DAC_CHANNEL_1);//读取前面设置DAC的值
LCD_ShowxNum(94,150,adcx,4,16,0); //显示DAC寄存器值
temp=(float)adcx*(3.3/4096); //得到DAC电压值
adcx=temp;
LCD_ShowxNum(94,170,temp,1,16,0); //显示电压值整数部分
temp-=adcx;
temp*=1000;
LCD_ShowxNum(110,170,temp,3,16,0X80); //显示电压值的小数部分
adcx=Get_Adc_Average(ADC_CHANNEL_5,10); //得到ADC转换值
temp=(float)adcx*(3.3/4096); //得到ADC电压值
adcx=temp;
LCD_ShowxNum(94,190,temp,1,16,0); //显示电压值整数部分
temp-=adcx;
temp*=1000;
LCD_ShowxNum(110,190,temp,3,16,0X80); //显示电压值的小数部分
t=0;
}
delay_ms(10);
4.驱动文件
PA4作为DAC的输出通道,先用按键控制给它一个数字,这个数字放到了DAC通道,放到DAC通道的信号是数字信号,然后读取DAC通道的值就是一个数字,将数字转换为对应的模拟电压(0-3300对应0-3.3V),这时可以读取出通道1的值进行转换得到模拟电压。
PA4和PA5用跳线帽相接,PA5作为ADC的输入通道,放到ADC通道的信号是模拟信号,然后读取通道的值就是一个模拟数字,转换为对应的数字电压(0-3300对应0-3.3V),再进行转换后得到一个数字电压的值。
pcf8574:
PCF8574是一个IO口的扩展芯片,2个io最多可以扩展64个io口。
1.hardware
IIC以及PCF8574
2.hallib
无
3.main
#include “pcf8574.h”
u8 beepsta=1; //pcf8574
PCF8574_Init(); //初始化PCF8574
if(key==KEY0_PRES)//KEY0按下,读取字符串并显示
{
beepsta=!beepsta; //蜂鸣器状态取反
PCF8574_WriteBit(BEEP_IO,beepsta); //控制蜂鸣器
}
if(PCF8574_INT==0) //PCF8574的中断低电平有效
{
key=PCF8574_ReadBit(EX_IO); //读取EXIO状态,同时清除PCF8574的中断输出(INT恢复高电平)
if(key==0)LED0_Toggle; //LED1状态取反
}
判断PCF8574_INT是为了分时复用,将EX_IO与一个低电平反复触碰的话就会触发PCF8574的中断。
4.驱动文件
IIC_Init();
同时初始化PB12(PCF8574的INT脚与stm32f767的PB12相接)为上拉输入;
将全部io置为高电平。
触摸屏:
1.hardware
24CXX以及touch
2.hallib
无
3.main
#include “touch.h”
u8 t1=0;u16 lastpos[5][2]; //触摸屏
tp_dev.init(); //触摸屏初始化
tp_dev.scan(0);
if(tp_dev.sta)
{
if(tp_dev.x[t1]《lcddev.width&&tp_dev.y[t1]《lcddev.height)
{
if(0《tp_dev.x[0]&&tp_dev.x[0]《60&&250《tp_dev.y[0]&&tp_dev.y[0]《350)
{
LED0_Toggle;//清除
PCF8574_WriteBit(BEEP_IO,0); //控制蜂鸣器
delay_ms(50);
PCF8574_WriteBit(BEEP_IO,1); //控制蜂鸣器
}
}
}
}
就是不用5点触控,直接一有触摸马上就反应。假设要画一个按键控制舵机转动的话可以参照下图:
4.驱动文件
u8 FT5206_Scan(u8 mode)中也去掉了5点触控的判断。
红外遥控:
1.hardware
remote
2.hallib
无
3.main
#include “remote.h”
Remote_Init(); //初始化 红外接收
key=Remote_Scan();
if(key)
{
LCD_ShowNum(86,130,key,3,16); //显示键值
LCD_ShowNum(86,150,RmtCnt,3,16); //显示按键次数
switch(key)
{
case 0:str=“ERROR”;break;
case 162:str=“POWER”;break;
case 98:str=“UP”;break;
case 2:str=“PLAY”;break;
case 226:str=“ALIENTEK”;break;
case 194:str=“RIGHT”;break;
case 34:str=“LEFT”;break;
case 224:str=“VOL-”;break;
case 168:str=“DOWN”;break;
case 144:str=“VOL+”;break;
case 104:str=“1”;TIM3_PWM_Init(1000-1,108-1);break;
case 152:str=“2”;TIM3_PWM_Init(2000-1,108-1);break;
case 176:str=“3”;TIM3_PWM_Init(3000-1,108-1);break;
case 48:str=“4”;TIM3_PWM_Init(4000-1,108-1);break;
case 24:str=“5”;TIM3_PWM_Init(5000-1,108-1);break;
case 122:str=“6”;break;
case 16:str=“7”;break;
case 56:str=“8”;break;
case 90:str=“9”;break;
case 66:str=“0”;break;
case 82:str=“DELETE”;break;
}
}else delay_ms(10);
LCD_Fill(86,170,86+8*8,170+16,WHITE); //清之前的显示
LCD_ShowString(86,170,200,16,16,str); //显示SYMBOL
这里注意一定要判断if(key),不然一直疯狂刷新界面。
4.驱动文件
红外遥控也是输入捕获,用的是定时器1的通道1,所以和pwm的定时器3不冲突。
FLASH:
1.hardware
STMFLASH
2.hallib
flash/flash.ex
3.main
#include “stmflash.h”
//要写入到STM32 FLASH的字符串数组
const u8 TEXT_Buffer[]={“STM32 FLASH TEST”};
#define TEXT_LENTH sizeof(TEXT_Buffer) //数组长度
#define SIZE TEXT_LENTH/4+((TEXT_LENTH%4)?1:0)
#define FLASH_SAVE_ADDR 0X08020000 //设置FLASH 保存地址(必须为4的倍数,且所在扇区,要大于本代码所占用到的扇区。
//否则,写操作的时候,可能会导致擦除整个扇区,从而引起部分程序丢失。引起死机。
u8 datatemp[SIZE];
LCD_ShowString(30,170,200,16,16,“Start Write FLASH.。..”);
STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)TEXT_Buffer,SIZE);
LCD_ShowString(30,170,200,16,16,“FLASH Write Finished!”);//提示传送完成
STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)datatemp,SIZE);
LCD_ShowString(30,170,200,16,16,“The Data Readed Is: ”);//提示传送完成
LCD_ShowString(30,190,200,16,16,datatemp);//显示读到的字符串
FLASH:
1.hardware
STMFLASH
2.hallib
flash/flash.ex
3.main
从PWM输出实验的工程开始,加入其他各种功能。
LCD屏幕显示:
一、hardware
其中timer是产生脉冲的。
二、hallib
FMC是一个接口,控制SDRAM和LCD
三、#include
#include “lcd.h” #include “sdram.h” 四、init()
SDRAM_Init(); //初始化SDRAM
LCD_Init(); //LCD初始化
这两个初始化是关键部分,首先SDRAM_Init(); 是SDRAM的底层驱动文件,LCD_Init();中会调用ltdc_init(),还会用到HAL_SDRAM_Init
USMART调试:
1.包含USMART文件夹以及它的path(不是hardware,么有hallib)
2.#include “usmart.h”
3.usmart_dev.init(108); //初始化USMART
4.usmart_config.c中,包含timer.h,在添加函数的地方添加TIM3_PWM_Init函数即可
5.打开串口调试助手直接发送TIM3_PWM_Init(999,107),同时可以随时更改舵机的转动角度。
RTC时钟:
1.hardware
rtc文件夹
2.hallib
stm32f7xx_hal_rtc.c
stm32f7xx_hal_rtc_ex.c
3.include
rtc.h
4.main
RTC_TimeTypeDef RTC_TimeStruct;
RTC_DateTypeDef RTC_DateStruct;
u8 tbuf[40];
u8 t=0;
RTC_Init(); //初始化RTC
t++;
if((t%10)==0) //每100ms更新一次显示数据
{
HAL_RTC_GetTime(&RTC_Handler,&RTC_TimeStruct,RTC_FORMAT_BIN);
sprintf((char*)tbuf,“Time:%02d:%02d:%02d”,RTC_TimeStruct.Hours,RTC_TimeStruct.Minutes,RTC_TimeStruct.Seconds);
LCD_ShowString(30,140,210,16,16,tbuf);
HAL_RTC_GetDate(&RTC_Handler,&RTC_DateStruct,RTC_FORMAT_BIN);
sprintf((char*)tbuf,“Date:20%02d-%02d-%02d”,RTC_DateStruct.Year,RTC_DateStruct.Month,RTC_DateStruct.Date);
LCD_ShowString(30,160,210,16,16,tbuf);
sprintf((char*)tbuf,“Week:%d”,RTC_DateStruct.WeekDay);
LCD_ShowString(30,180,210,16,16,tbuf);
}
5.usmart
6.rtc.c中
中断处理回调函数:
#include “timer.h”
//RTC闹钟A中断处理回调函数
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
printf(“ALARM A!rn”);
TIM3_PWM_Init(1000*-1,108-1);
}
待机唤醒:
1.hardware
wkup
2.hallib
无
3.include
#include “wkup.h” 4.main
WKUP_Init(); //待机唤醒初始化
LCD_Init(); //初始化LCD
LCD_Init必须要在WKUP_Init之后,每次点击按键都会进入到main函数中,那么都会进入到WKUP_Init():
//WKUP_Init:
if(Check_WKUP()==0)
{
Sys_Enter_Standby();//不是开机,进入待机模式
}
//按键中断:
if(Check_WKUP())//关机
{
Sys_Enter_Standby();//进入待机模式
}
假如按下没有3秒,就直接Check_WKUP()==0进入待机;假如按下有3秒,跳过了Sys_Enter_Standby()可以正常开机,同时打开按键中断。如果开机后按下没有3秒,进入中断判断就不会进入Sys_Enter_Standby();如果开机后按下有3秒,直接进入待机。
TPAD:
1.hardware
tpad
2.hallib
无
3.include
#include “tpad.h”
4.main
TPAD_Init(8); //初始化触摸按键,以108/8=13.5Mhz频率计数
switch (TPAD_Scan(0)) //成功捕获到了一次上升沿(此函数执行时间至少15ms)
{
case 0:
LCD_LED(1); //开背光
LED1(1);
break;
case 1:
LCD_LED(0); //关背光
LED1(0);
break;
}
switch (TPAD_Scan(0)) 在while(1)里面循环。
5.tpad.c
u8 TPAD_Scan(u8 mode)
{
static u8 keyen=0; //0,可以开始检测;》0,还不能开始检测
static u8 res=0;
u8 sample=3; //默认采样次数为3次
u16 rval;
if(mode)
{
sample=6; //支持连按的时候,设置采样次数为6次
keyen=0; //支持连按
}
rval=TPAD_Get_MaxVal(sample);
if(rval》(tpad_default_val*4/3)&&rval《(10*tpad_default_val))//大于tpad_default_val+TPAD_GATE_VAL,且小于10倍tpad_default_val,则有效
{
if(keyen==0)res++; //大于tpad_default_val+TPAD_GATE_VAL,有
//printf(“r:%drn”,rval);
keyen=3; //至少要再过3次之后才能按键有效
}
if(keyen)keyen--;
res=res%2;
return res;
}
首先默认的是time2的通道1,gpio是pa5,然而pa5会和后面的ADC冲突,所以选择time2的通道3,gpio是pa2。
更改GPIO_PIN_2、TIM_CHANNEL_3即可,GPIO_AF1_TIM2不用管。
ADC:
1.hardware
ADC
2.hallib
adc.c以及adc_ex.c
3.main
#include“adc.h”
u16 adcx;float temp;
MY_ADC_Init(); //初始化ADC1通道
adcx=Get_Adc_Average(ADC_CHANNEL_5,20);//获取通道5的转换值,20次取平均
LCD_ShowxNum(134,130,adcx,4,16,0); //显示ADCC采样后的原始值
temp=(float)adcx*(3.3/4096); //获取计算后的带小数的实际电压值,比如3.1111
adcx=temp; //赋值整数部分给adcx变量,因为adcx为u16整形
LCD_ShowxNum(134,150,adcx,1,16,0); //显示电压值的整数部分,3.1111的话,这里就是显示3
temp-=adcx; //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111
temp*=1000; //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
LCD_ShowxNum(150,150,temp,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111.
4.驱动文件
ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
GPIO_Initure.Pin=GPIO_PIN_5; //PA5
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
Get_Adc_Average(ADC_CHANNEL_5,20)是要得到通道5的值,所以要初始化PA5,假如是内部温度传感器,它是接的通道18,就不用管PA5,HAL_ADC_MspInit中只用使能ADC1时钟即可,Get_Temprate函数会得到通道18的电压值,temperate=(float)adcx*(3.3/4096);默认的参考电压都是0-3.3V,而12位的分辨率,通道里面得到的是数字,经过转换就可以得到对应的电压。
DAC:
1.hardware
DAC
2.hallib
dac.c以及dac_ex.c
3.main
#include “dac.h”
u16 dacval=0;u8 key;
DAC1_Init(); //初始化DAC1
LCD_ShowString(30,150,200,16,16,“DAC VAL:”);
LCD_ShowString(30,170,200,16,16,“DAC VOL:0.000V”);
LCD_ShowString(30,190,200,16,16,“ADC VOL:0.000V”);
key=KEY_Scan(0);
if(key==KEY2_PRES)
{
if(dacval《4000)dacval+=200;
HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dacval);//设置DAC值
}else if(key==KEY1_PRES)
{
if(dacval》200)dacval-=200;
else dacval=0;
HAL_DAC_SetValue(&DAC1_Handler,DAC_CHANNEL_1,DAC_ALIGN_12B_R,dacval);//设置DAC值
}
if(t==10||key==KEY1_PRES||key==KEY2_PRES) //WKUP/KEY1按下了,或者定时时间到了
{
adcx=HAL_DAC_GetValue(&DAC1_Handler,DAC_CHANNEL_1);//读取前面设置DAC的值
LCD_ShowxNum(94,150,adcx,4,16,0); //显示DAC寄存器值
temp=(float)adcx*(3.3/4096); //得到DAC电压值
adcx=temp;
LCD_ShowxNum(94,170,temp,1,16,0); //显示电压值整数部分
temp-=adcx;
temp*=1000;
LCD_ShowxNum(110,170,temp,3,16,0X80); //显示电压值的小数部分
adcx=Get_Adc_Average(ADC_CHANNEL_5,10); //得到ADC转换值
temp=(float)adcx*(3.3/4096); //得到ADC电压值
adcx=temp;
LCD_ShowxNum(94,190,temp,1,16,0); //显示电压值整数部分
temp-=adcx;
temp*=1000;
LCD_ShowxNum(110,190,temp,3,16,0X80); //显示电压值的小数部分
t=0;
}
delay_ms(10);
4.驱动文件
PA4作为DAC的输出通道,先用按键控制给它一个数字,这个数字放到了DAC通道,放到DAC通道的信号是数字信号,然后读取DAC通道的值就是一个数字,将数字转换为对应的模拟电压(0-3300对应0-3.3V),这时可以读取出通道1的值进行转换得到模拟电压。
PA4和PA5用跳线帽相接,PA5作为ADC的输入通道,放到ADC通道的信号是模拟信号,然后读取通道的值就是一个模拟数字,转换为对应的数字电压(0-3300对应0-3.3V),再进行转换后得到一个数字电压的值。
pcf8574:
PCF8574是一个IO口的扩展芯片,2个io最多可以扩展64个io口。
1.hardware
IIC以及PCF8574
2.hallib
无
3.main
#include “pcf8574.h”
u8 beepsta=1; //pcf8574
PCF8574_Init(); //初始化PCF8574
if(key==KEY0_PRES)//KEY0按下,读取字符串并显示
{
beepsta=!beepsta; //蜂鸣器状态取反
PCF8574_WriteBit(BEEP_IO,beepsta); //控制蜂鸣器
}
if(PCF8574_INT==0) //PCF8574的中断低电平有效
{
key=PCF8574_ReadBit(EX_IO); //读取EXIO状态,同时清除PCF8574的中断输出(INT恢复高电平)
if(key==0)LED0_Toggle; //LED1状态取反
}
判断PCF8574_INT是为了分时复用,将EX_IO与一个低电平反复触碰的话就会触发PCF8574的中断。
4.驱动文件
IIC_Init();
同时初始化PB12(PCF8574的INT脚与stm32f767的PB12相接)为上拉输入;
将全部io置为高电平。
触摸屏:
1.hardware
24CXX以及touch
2.hallib
无
3.main
#include “touch.h”
u8 t1=0;u16 lastpos[5][2]; //触摸屏
tp_dev.init(); //触摸屏初始化
tp_dev.scan(0);
if(tp_dev.sta)
{
if(tp_dev.x[t1]《lcddev.width&&tp_dev.y[t1]《lcddev.height)
{
if(0《tp_dev.x[0]&&tp_dev.x[0]《60&&250《tp_dev.y[0]&&tp_dev.y[0]《350)
{
LED0_Toggle;//清除
PCF8574_WriteBit(BEEP_IO,0); //控制蜂鸣器
delay_ms(50);
PCF8574_WriteBit(BEEP_IO,1); //控制蜂鸣器
}
}
}
}
就是不用5点触控,直接一有触摸马上就反应。假设要画一个按键控制舵机转动的话可以参照下图:
4.驱动文件
u8 FT5206_Scan(u8 mode)中也去掉了5点触控的判断。
红外遥控:
1.hardware
remote
2.hallib
无
3.main
#include “remote.h”
Remote_Init(); //初始化 红外接收
key=Remote_Scan();
if(key)
{
LCD_ShowNum(86,130,key,3,16); //显示键值
LCD_ShowNum(86,150,RmtCnt,3,16); //显示按键次数
switch(key)
{
case 0:str=“ERROR”;break;
case 162:str=“POWER”;break;
case 98:str=“UP”;break;
case 2:str=“PLAY”;break;
case 226:str=“ALIENTEK”;break;
case 194:str=“RIGHT”;break;
case 34:str=“LEFT”;break;
case 224:str=“VOL-”;break;
case 168:str=“DOWN”;break;
case 144:str=“VOL+”;break;
case 104:str=“1”;TIM3_PWM_Init(1000-1,108-1);break;
case 152:str=“2”;TIM3_PWM_Init(2000-1,108-1);break;
case 176:str=“3”;TIM3_PWM_Init(3000-1,108-1);break;
case 48:str=“4”;TIM3_PWM_Init(4000-1,108-1);break;
case 24:str=“5”;TIM3_PWM_Init(5000-1,108-1);break;
case 122:str=“6”;break;
case 16:str=“7”;break;
case 56:str=“8”;break;
case 90:str=“9”;break;
case 66:str=“0”;break;
case 82:str=“DELETE”;break;
}
}else delay_ms(10);
LCD_Fill(86,170,86+8*8,170+16,WHITE); //清之前的显示
LCD_ShowString(86,170,200,16,16,str); //显示SYMBOL
这里注意一定要判断if(key),不然一直疯狂刷新界面。
4.驱动文件
红外遥控也是输入捕获,用的是定时器1的通道1,所以和pwm的定时器3不冲突。
FLASH:
1.hardware
STMFLASH
2.hallib
flash/flash.ex
3.main
#include “stmflash.h”
//要写入到STM32 FLASH的字符串数组
const u8 TEXT_Buffer[]={“STM32 FLASH TEST”};
#define TEXT_LENTH sizeof(TEXT_Buffer) //数组长度
#define SIZE TEXT_LENTH/4+((TEXT_LENTH%4)?1:0)
#define FLASH_SAVE_ADDR 0X08020000 //设置FLASH 保存地址(必须为4的倍数,且所在扇区,要大于本代码所占用到的扇区。
//否则,写操作的时候,可能会导致擦除整个扇区,从而引起部分程序丢失。引起死机。
u8 datatemp[SIZE];
LCD_ShowString(30,170,200,16,16,“Start Write FLASH.。..”);
STMFLASH_Write(FLASH_SAVE_ADDR,(u32*)TEXT_Buffer,SIZE);
LCD_ShowString(30,170,200,16,16,“FLASH Write Finished!”);//提示传送完成
STMFLASH_Read(FLASH_SAVE_ADDR,(u32*)datatemp,SIZE);
LCD_ShowString(30,170,200,16,16,“The Data Readed Is: ”);//提示传送完成
LCD_ShowString(30,190,200,16,16,datatemp);//显示读到的字符串
FLASH:
1.hardware
STMFLASH
2.hallib
flash/flash.ex
3.main
举报