序文
明日はブルーブリッジカップ大会です。最終日は、各モジュールの使い方とコードの書き方を整理し直します。各モジュールのMX構成が以前に送信したものに基づいている場合、この記事のコードは完全に適用可能です。そうでない場合、主要部分は同じであり、コード部分が適用可能である場合は、参照として自分で判断できます。 。
導いた
ピン:
PC8~PC15(LED1 ~ LED8)
1. LEDライトのオン/オフを制御する場合は、PD2ピンのレベルを変更する必要があります(最初にハイ、次にロー)
。2。データがラッチされていない場合、データを保存できません。3
. LCDを操作する場合、 LED
4に影響します。ラッチ:
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
5.アレイを使用してLCDとの競合を解決します
鍵
ピン:
PB0 ------> B0
PB1 ------> B1
PB2 ------> B2
PA0 ------> B3
1.ボタンが押されていると判断するHAL_GPIO_ReadPin();
2.ボタンは5〜10msの間ジッターを解除できます
3.ボタンが離されたことをwhlieが検出します
I2C-EEPROM
1.文字列を書き込む場合、通常は複数バイトです。バイト書き込み関数を複数回呼び出す必要があります。関数をマルチバイト書き込み関数として直接書き込むことができます。
void EEPROM_WriteBuff(uint8_t addr,uint8_t *sendBuff,uint32_t numByteToWrite)//EEPROM写数据
{
I2CStart();//开始通信 起始信号
I2CSendByte(0xa0);//发送从设备地址 EEPROM地址为0XA0 最后一位数据为0方向为写入
I2CWaitAck();//等待应答
I2CSendByte(addr);//发送存储地址
I2CWaitAck();//等待应答
while(numByteToWrite--)//连续写入
{
I2CSendByte(*sendBuff);//发送数据
I2CWaitAck();//等待应答
sendBuff++;//指针自增
}
I2CStop();//结束通信 发送终止信号
}
void EEPROM_ReadBuff(uint8_t addr,uint8_t *readBuff,uint32_t numByteToRead)//EEPROM读数据
{
I2CStart();//开始通信 起始信号
I2CSendByte(0xa0);//发送从设备地址 EEPROM地址为0XA0 最后一位数据为0方向为写入
I2CWaitAck();//等待应答
I2CSendByte(addr);//发送存储地址
I2CWaitAck();//等待应答
I2CStart();//再次发送起始信号
I2CSendByte(0xa1);//发送从设备地址 EEPROM地址为0XA0 最后一位数据为1方向为读取
I2CWaitAck();//等待应答
while(numByteToRead--)//连续读取
{
*readBuff=I2CReceiveByte();//读取一字节数据
if(numByteToRead==0)//如果读取结束
{
I2CSendNotAck();//主机发送非应答
}
else//未结束
{
readBuff++;//指针自增
I2CSendAck();//主机发送应答信号 继续接收下一字节数据
}
}
I2CStop();//结束通信 发送终止信号
}
2.連続的な読み取りと書き込みに加えて遅延待機。マイクロコントローラーの動作周波数はEEPROMの動作周波数よりもはるかに高く、データが完全に保存または読み取られるまで待つ必要があります。3.に
保存されているアドレスEEPROMは大きすぎてはいけません(0から開始するだけ
です)4。EEPROMデバイスアドレスは0XA0(書き込み方向)0XA1(読み取り方向)
です。5。データのバイトが書き込まれるたびに、I2CWaitAck()を呼び出す必要があります; //返事を待っている
LCD
ピン:
PC8~PC15
1.使用する前にLCD_Init()を初期化します
。2。各行の長さは20単位です。3。0
から9までの10行があります
。4。各文字の高さは24、幅は16
です。5。機能:
显示一行 LCD_DisplayStringLine(Line0,(unsigned char *)" ");
显示单个字符 LCD_DisplayChar(u8 Line, u16 Column, u8 Ascii); (第一个参数为纵坐标,字符高度为24;第二个参数为横 坐标,字符宽度为16;屏幕最右边横坐标为0,最坐边为19*16)
RTC
1.構成:
A.使能时钟源
B.使能日历
C.开启闹钟
D.开启中断
E.配置初始化时间
F.配置闹钟参数
2.構造:
时间结构体 RTC_TimeTypeDef
日期结构体 RTC_DateTypeDef
闹钟结构体 RTC_AlarmTypeDef
3.機能:
开启闹钟中断 HAL_RTC_SetAlarm_IT(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint32_t Format);
回调函数 HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc);
读取时间 HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);
读取日期 HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);
设置时间 HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD);
设置闹钟 HAL_RTC_SetAlarm_IT(&hrtc,&sAlarm, RTC_FORMAT_BIN);
4.注:
時間を読んだ後、歩き続けるには日付時計を読む必要があります
5. 2番目の割り込みコード:
RTC_AlarmTypeDef sAlarm = {
0};//将生成代码中的这一结构体定义为全局变量,并将生成的这一行代码删除
void Get_Time() //获取当前时间
{
HAL_RTC_GetTime(&hrtc,&Now_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc,&Now_Date,RTC_FORMAT_BIN);
}
void Show_Now_Time()//显示当前时间
{
char str[30];
sprintf(str," T:%02d-%02d-%02d ",Now_Time.Hours,Now_Time.Minutes,Now_Time.Seconds);
LCD_DisplayStringLine(Line6,(unsigned char*)str);
}
void Set_Alarm() //设置下一秒的闹钟
{
sAlarm.AlarmTime.Seconds = Now_Time.Seconds+1;
if(sAlarm.AlarmTime.Seconds==60)sAlarm.AlarmTime.Seconds=0;
HAL_RTC_SetAlarm_IT(&hrtc,&sAlarm, RTC_FORMAT_BIN);
}
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)//RTC闹钟中断 时间显示(每秒)
{
Get_Time();//获取发生中断的时间
Set_Alarm();//设定下一秒的闹钟
Show_Now_Time();//显示当前时间
}
ADC
ピン:
PB1 ------> ADC1_IN12
PB12 ------> ADC1_IN11
PB15 ------> ADC2_IN15
1.AD変換値の上限は4096です
。2。割り込みを開く必要はありません。3
。構成
A.使用MX初始化时直接默认配置即可
4.機能:
开启ADC HAL_ADC_Start(ADC_HandleTypeDef *hadc);
读取ADC的转换值 HAL_ADC_GetValue(ADC_HandleTypeDef *hadc)(每次getvalue之前都需要先Start);
5.コード:
double ADC_GetValue()
{
uint32_t count;//保存计数值
HAL_ADC_Start(&hadc2);//每次GetValue前都需要重新Start
count=HAL_ADC_GetValue(&hadc2);
return count*3.3/4096;
}
USART(mxで構成するときにピンとGPIOクロックを変更する)!
注:HAL_USART_MspInit()およびHAL_USART_MspDeInit()を変更する必要があります
ピン:
PA8 ------> USART1_CK
PA9 ------> USART1_TX
PA10 ------> USART1_RX
1.パラメーター構成:
モード非同期通信
PIN GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;(MXの構成が正しくありません)
2。機能:
发送 HAL_USART_Transmit(&husart1,(unsigned char *)str,strlen(str),100); 注意长度
printf重定向 int fputc(int ch,FILE *f)
{
HAL_USART_Transmit(&husart1,(uint8_t *)&ch,1,100);
return ch;
}
接收中断 HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)(每接收size字节数据中断一次)
接收中断回调函数 HAL_UART_RxCpltCallback( UART_HandleTypeDef * huart ) (每次中断后需要重新开启接收中断)
TIM
1.基本タイマー:(TIM6 TIM7)
A.パラメーター構成:
Prescaler(PSC) 预分频值,决定定时器工作频率
Counter Mode 计数模式
Counter Period 重装载值
Trigger Event Selection 触发事件
B.機能:
回调函数 HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
以中断方式开启定时器 HAL_TIM_Base_Start_IT(&htim6);
关闭定时器 HAL_TIM_Base_Stop_IT(&htim6);
2.高度なタイマー:(入力周波数測定)
A。パラメーター構成:
模式选择输入捕获
使能定时器中断
B.機能:
初始化函数启动输入捕获中断模式
获取定时器计数值 __HAL_TIM_GET_COUNTER(&htimx);//读TIMX->CNT也可以
设置定时器计数值 __HAL_TIM_SetCounter(&htimx,0);//清零 TIM->CNT=0也可以
输入捕获回调函数 HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim);//测量频率
//在中断模式下启动TIM输入捕获测量 HAL_TIM_IC_Start_IT(&htimx, TIM_CHANNEL_x);//使用此函数时必须在主函数先调用一次
C.例:(TIMは入力周波数を測定します)
タイマーが中断された後、現在のカウント値はコールバック関数で取得され、入力周波数は分周されたクロック周波数/カウント値を使用して取得できます。クリアする必要があります。カウンタをオンにして、次の測定の割り込みをオンにします
。D。入力周波数のデューティサイクルを測定します。入力キャプチャのキャプチャ方法をダブルエッジキャプチャに変更する必要があります。つまり、割り込みが発生します。立ち上がりエッジと立ち下がりエッジの両方で、高レベルのカウント値を低電力で除算します。デューティサイクルは、カウント値を平均することで得られます。
PWM
1.構成:
A.选择引脚功能为TIMx_CHx
B.将定时器对应通道功能选择为PWM输出
C.Prescaler为分频系数。将系统时钟进行分频
D.Counter为溢出值
E.Pulse是一个阈值,区分Pulse/Counter之前与之后的电平
F.配置的参数都减一
2.機能:
回调函数 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim);
开启PWM HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
停止PWM HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);
配置占空比 __HAL_TIM_SET_COMPARE;
3.例:
周波数1KHz、デューティサイクル80%のPWM周波数を出力
=クロック周波数/プリスケーラ/カウンタクロック周波数が80MHzの場合、プリスケーラを80に、カウンタを1000に設定します。周波数は1KHz
デューティサイクル:高レベル時間/ 1サイクル時間、1KHzは1msのサイクル時間に対応、パルスは800に設定可能、カウント値が0〜800の場合は高レベルを出力、時間は8/10サイクルまたは0.8ms、801〜1000の場合の出力低レベル、使用可能なデューティサイクルは80%
4. PWM出力ピンを使用して連続的なハイレベルまたはローレベルを出力する場合は、GPIOモードを変更する必要があります。コードは次のとおりです(13のシミュレーション質問)
void PWM_Out(double R37_V,uint32_t FRQ,uint8_t R) //PWM输出
{
uint32_t Period;//配置重装载值
uint32_t Pulse;//配置占空比
GPIO_InitTypeDef GPIO_InitStruct;//重新配置GPIO 默认为PWM输出
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
if(R37_V<0.01)//如果R37电压值为0V
{
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_2);//PWM关闭
GPIO_InitStruct.Mode =GPIO_MODE_OUTPUT_PP;//配置为通用推挽输出 如不配置 无法正常输出高低电平
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //重新初始化
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);//输出低电平
}
else if(R37_V>3.29)//如果R37电压值为3.3V
{
HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_2);//PWM关闭
GPIO_InitStruct.Mode =GPIO_MODE_OUTPUT_PP;//配置为通用推挽输出
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //重新初始化
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);//输出低电平
}
else if(R37_V>0 && R37_V<3.3)//输入PWM
{
Period=TIM_Clock/(FRQ/R)-1;//输出PWM的重装载值=(定时器时钟频率/目标频率)-1
Pulse=R37_V/3.3*Period-1;//输出PWM的Pulse=(R37电压值/3.3*重装载值)-1
TIM3->ARR=Period;//直接对寄存器进行配置
TIM3->CCR2=Pulse;
HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//开启PWM
}
}
要約する
以上がすべての内容ですので、誤りがございましたら、批判・訂正をお願いします。
ゲームの前にうまく整理して、ゲームで通常のレベルをプレイするように努力してください。明日はみんなが勝つことを願っています〜