前言
学的时候也没看见什么有G4的教程,怕以后忘了做个记录
1、clear_it 和clear_flag不一样的,要注意
一、adc
1、时钟是一般是独立
2、单个adc通道保存默认就好
3、规则通道,12位精度,单次转换,软件触发,采样时间关乎精度
生成的初始代码没有校准,记得加上校准,不然不准。
u16 adc_get(ADC_HandleTypeDef* hadc){
HAL_ADC_Start(hadc);
HAL_ADC_PollForConversion(hadc,10);
return HAL_ADC_GetValue(hadc);
}
获得adc的值,然后处理就好。
二、dac
1、仅连接外部引脚
2、参数默认,output buffer是提高带负载能力的,可以关
3、精度12位
HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef *hdac, uint32_t Channel);
直接开启就行。
usart
HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)这函数的意思是接收到指定个数的数据后就调用回调函数。pData可以是一个数组,当接收到size个数据后就会把这几个数据依次放到pData里。
1、异步
2、dma接收,空闲中断结束
main
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
HAL_UART_Receive_DMA(&huart1,rx_buffer,20);
if(rx_flag&0x80){
HAL_UART_Transmit(&huart1,rx_buffer,rx_flag&(~0x80),10);
HAL_UART_Receive_DMA(&huart1,rx_buffer,20);
rx_flag=0;
}
it
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)){
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_DMAStop(&huart1);
if(rx_flag==0){
rx_flag|=0x80;
rx_flag+=20-__HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
}else{
HAL_UART_Receive_DMA(&huart1,rx_buffer,20);
}
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
led
这板子led和lcd引脚交叉,用了74hc573,其他没啥了,
用个变量表示led的状态,操作时直接赋值给端口。
#define led1 (1<<8)
#define led2 (1<<9)
#define led3 (1<<10)
#define led4 (1<<11)
#define led5 (1<<12)
#define led6 (1<<13)
#define led7 (1<<14)
#define led8 (1<<15)
#define led_all (0xff00)
void led_control(u16 led,u8 state){
u16 temp=GPIOC->ODR;
if(state){
led_date|=led;
}else{
led_date&=(~led);
}
GPIOC->ODR=led_date;
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,1);
HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,0);
GPIOC->ODR=temp;
}
rtc
1、用的内部时钟32M
2、根据手册知道分频值
3、date format我习惯用二进制的
void get_rtc(void){
static u8 send=70;
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
HAL_RTC_GetTime(&hrtc,&sTime,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc,&sDate,RTC_FORMAT_BIN);
if(sTime.Seconds!=send){
send=sTime.Seconds;
printf("%u,%u,%u\r\n",sTime.Hours,sTime.Minutes,sTime.Seconds);
printf("%u,%u,%u\r\n",sDate.Year,sDate.Month,sDate.Date);
}
}
/* USER CODE BEGIN Check_RTC_BKUP */
if(HAL_RTCEx_BKUPRead(&hrtc,0x00)!=0xaadd){
HAL_RTCEx_BKUPWrite(&hrtc,0x00,0xaadd);
/* USER CODE END Check_RTC_BKUP */
4、获取时间是一个完整过程,先gettime,再getdate,必须按这顺序,不然会出错。
5、如果想保存复位不跟新rtc时间,就上电时在后备区写个值,通过判断这个值来确定是否时是首次上电,不是就进行初始日历。