序文
1. 電圧の校正方法
2. タイムジャンプ
1. ADCを取得する
# include "badc.h"
double getADC(ADC_HandleTypeDef *pin){
uint adc;
HAL_ADC_Start(pin);
adc=HAL_ADC_GetValue(pin);
return adc*3.3/4096;
}
}
2. RTC の日付と時刻を取得します。
void get_time(void) //获取时间
{
HAL_RTC_GetDate (&hrtc, &data,RTC_FORMAT_BIN);
HAL_RTC_GetTime (&hrtc, &time, RTC_FORMAT_BIN );
}
3. 出力関数を書き換える
int fputc(int c,FILE*stream){
HAL_UART_Transmit(&huart1,(unsigned char*)&c,1,1000);
return 1;
}
4. I2C 読み取りおよび書き込み機能
1. データの読み取り
uchar eeprom_read(uchar addr){
uchar dat;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CStop();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
dat=I2CReceiveByte();
I2CWaitAck();
I2CStop();
return dat;
}
2. データの書き込み
void eeprom_write (uchar addr,uchar dat){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
5. ボタン
1. 4 つのボタンをスキャンしてデバウンスします
タイマー 3 をオンにし、10ms の割り込みスキャンとして設定します。
1.interrupt.cファイル
#include "interrupt.h"
struct keys key[4]={
0, 0, 0} ;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM3){
key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i=0;i<4;i++){
switch(key[i].judge_sta){
case 0:
{
if(key[i].key_sta==0)key[i].judge_sta=1;
}
break;
case 1:
{
if(key[i].key_sta==0){
key[i].judge_sta=2;
key[i].single_flage=1;
}
else
key[i].judge_sta=0;
}
break;
case 2:
{
if(key[i].key_sta==1)//松开
key[i].judge_sta=0;
}
break;
}
}
}
}
2.interrupt.h ファイル
#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_
#include "main.h"
#include "stdbool.h"
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
struct keys{
uchar judge_sta;//消抖过程的状态
bool key_sta;//按键的高低电平
bool single_flage;//是否按下的标志
};
#endif
3. .C ファイルを長押しします。
#include "interrupt.h"
struct keys key[4]={
0, 0, 0} ;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM3){
key[0].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key[1].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key[2].key_sta=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key[3].key_sta=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i=0;i<4;i++){
switch(key[i].judge_sta){
case 0:
{
if(key[i].key_sta==0){
key[i].judge_sta=1;
key[i].key_time=0;
}
break;
case 1:
{
if(key[i].key_sta==0){
key[i].judge_sta=2;
//按键摁下标志
}
else
key[i].judge_sta=0;
}
break;
case 2:
{
if(key[i].key_sta==1)//松开
{
key[i].judge_sta=0;
key[i].single_flage=1;//松开确定摁下
if(key[i].key_time<70){
key[i].single_flage=1;//松开确定摁下、短按键
}
}
else{
key[i].key_time++;
if(key[i].key_time>70){
key[i].long_flage=1;//长按键
}
}
}
break;
}
}
}
}
}
4. .h ファイルを長押しします。
#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_
#include "main.h"
#include "stdbool.h"
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
struct keys{
uchar judge_sta;//消抖过程的状态
bool key_sta;//按键的高低电平
bool single_flage;//是否按下的标志
bool long_flage;//长按键的标志
uint key_time;//长按时间
};
#endif
6. LED
1、LED.C
# include"led.h"
void LED_Disp(uchar dsLED){
HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC,dsLED<<8,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);//pd2置一,打开锁存器
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);//pd2置一,打开锁存器
}
2、led.h
#ifndef _LED_H_
#define _LED_H_
#include "main.h"
void LED_Disp(uchar dsLED);
#endif
3. main.h のマクロ定義 uchar および uint
七、液晶操作
lcd.h、font.h、lcd.c ファイルを bsp にコピーし、bsp パスを追加して、.c ファイルを追加します。
8.タイマー
1. 上級: 1 および 8
2. 一般: 2、3、4、15、16、17
3. 基本: 6、7
4. タイマーを刻む
1. キャプチャ タイマーの周波数とデューティ サイクル
double ccrl_val1=0,ccrl_val2=0;
int ccrl_val1b=0,ccrl_val2b=0;
uint frq1=0,frq2=0;
float duty1=0,duty2=0;//占空比
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim){
if(htim->Instance==TIM2){
if(htim->Channel==HAL_TIM_ACTIVE_CHANNEL_1){
//中断消息来源选择直接输入的通道
ccrl_val1=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_1);//直接
ccrl_val1b=HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2);//间接
__HAL_TIM_SetCounter(htim,0);
frq1=(80000000/80)/ccrl_val1;
duty1=(ccrl_val1b/ccrl_val1)*100;
HAL_TIM_IC_Start(htim,TIM_CHANNEL_1);
HAL_TIM_IC_Start(htim,TIM_CHANNEL_2);
}
}
}
2. シリアルポート
char rxdata[30];
uint8_t rxdat;
uchar rx_pointer;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *hurat){
rxdata[rx_pointer++]=rxdat;
HAL_UART_Receive_IT(&huart1,&rxdat,1);
}
3. 割り込み機能
#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_
#include "main.h"
#include "stdbool.h"
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);
struct keys{
uchar judge_sta;//消抖过程的状态
bool key_sta;//按键的高低电平
bool single_flage;//是否按下的标志
bool long_flage;//长按键的标志
uint key_time;//长按时间
};
#endif
ボタンをずっと押し続ける
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//回调函数
{
if(htim->Instance==TIM3)//定时器3的事件
{
key_state[0]=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_0);
key_state[1]=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_1);
key_state[2]=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_2);
key_state[3]=HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
for(int i=0;i<4;i++)
{
switch (judge_state[i])
{
case 0:
{
if(key_state[i]==0)//按键按下
{
judge_state[i]=1;
key_time[i]=0;
}
break;
}
case 1://消抖过程
{
if(key_state[i]==0)
{
judge_state[i]=2;
}
else judge_state[i]=0;//未按下
break;
}
case 2:
{
if((key_state[i]==1)&&key_time[i]<70)//等待松开过程,且非长按键
{
if(double_click_timerEN[i]==0) //可能双击按键的第一次,进入计时
{
double_click_timerEN[i]=1;
double_click_time[i]=0;
}
else //在计时范围内又按了一次
{
double_key_flag[i]=1;//双击情况
double_click_timerEN[i]=0;
}
judge_state[i]=0;
}
else if(key_state[i]==1&&key_time[i]>=70) judge_state[i]=0;//松开且是长按键
else
{
if (key_time[i]>=70)long_key_flag[i]=1;//长按键
key_time[i]++;//长按键计时 还没松开
}
break;
}
}
if(double_click_timerEN[i]==1)//延时确认是否双击
{
double_click_time[i]++;
if(double_click_time[i]>=35)
{
single_key_flag[i]=1;//按键1单次按下
double_click_timerEN[i]=0;
}
}
}
}
}
9. まとめ
これは私がレビューする際にさまざまな場所から探したテンプレートを少しまとめたものですので、ご参考になれば幸いです。