- #include "at32m412_416_board.h"
- #include "at32m412_416_clock.h"
- #include "i2c_application.h"
- #include "oled.h"
- #include "at32m412_416_adc.h"
- #include "NTC.h"
- extern i2c_handle_type hi2cx;
- #define DELAY 100
- #define FAST 1
- #define SLOW 4
- uint8_t g_speed = FAST;
- uint8_t ioIndex =0x00;
- void button_exint_init(void);
- void button_B4_isr(void);
- void button_B5_isr(void);
- void button_B7_isr(void);
- void button_B10_isr(void);
- void Write_IIC_Command(unsigned char IIC_Command);
- void Write_IIC_Data(unsigned char IIC_Data);
- void OLED_WR_Byte(unsigned dat,unsigned cmd);
- void i2c_lowlevel_init(i2c_handle_type* hi2c);
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] configure button exint
- * @param none
- * @retval none
- */
- //void button_exint_init(void)
- //{
- // exint_init_type exint_init_struct;
- // crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
- // scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOA, SCFG_PINS_SOURCE0);
- // exint_default_para_init(&exint_init_struct);
- // exint_init_struct.line_enable = TRUE;
- // exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
- // exint_init_struct.line_select = EXINT_LINE_0;
- // exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
- // exint_init(&exint_init_struct);
- // nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
- // nvic_irq_enable(EXINT0_IRQn, 0, 0);
- //}
- void button_exint_init(void)
- {
- exint_init_type exint_init_struct;
- crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
- scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE4);
- scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE5);
- scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE7);
- scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE10);
-
- exint_default_para_init(&exint_init_struct);
- exint_init_struct.line_enable = TRUE;
- exint_init_struct.line_mode = EXINT_LINE_INTERRUPT;
- exint_init_struct.line_select = EXINT_LINE_4 | EXINT_LINE_5 | EXINT_LINE_7 | EXINT_LINE_10;
- exint_init_struct.line_polarity = EXINT_TRIGGER_FALLING_EDGE;
- exint_init(&exint_init_struct);
- nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
- nvic_irq_enable(EXINT4_IRQn, 0, 0);
- nvic_irq_enable(EXINT9_5_IRQn, 0, 0);
- nvic_irq_enable(EXINT15_10_IRQn, 0, 0);
- }
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] button handler function
- * @param none
- * @retval none
- */
- void button_B4_isr(void)
- {
- /* delay 5ms */
- delay_ms(5);
- /* clear interrupt pending bit */
- exint_flag_clear(EXINT_LINE_4);
- /* check input pin state */
- if(RESET == gpio_input_data_bit_read(GPIOB, GPIO_PINS_4))
- {
- ioIndex = 0x03;
- }
- printf("GPIOB_04 is pressed.\r\n");
- }
- void button_B5_isr(void)
- {
- /* delay 5ms */
- delay_ms(5);
- /* clear interrupt pending bit */
- exint_flag_clear(EXINT_LINE_5);
- /* check input pin state */
- if(RESET == gpio_input_data_bit_read(GPIOB, GPIO_PINS_5))
- {
- ioIndex = 0x04;
- printf("GPIOB_05 is pressed.\r\n");
- }
- }
- void button_B7_isr(void)
- {
- /* delay 5ms */
- delay_ms(5);
- /* clear interrupt pending bit */
- exint_flag_clear(EXINT_LINE_7);
- /* check input pin state */
- if(RESET == gpio_input_data_bit_read(GPIOB, GPIO_PINS_7))
- {
- ioIndex = 0x01;
- printf("GPIOB_07 is pressed.\r\n");
- }
-
- }
- void button_B10_isr(void)
- {
- /* delay 5ms */
- delay_ms(5);
- /* clear interrupt pending bit */
- exint_flag_clear(EXINT_LINE_10);
- /* check input pin state */
- if(RESET == gpio_input_data_bit_read(GPIOB, GPIO_PINS_10))
- {
- ioIndex = 0x02;
- printf("GPIOB_10 is pressed.\r\n");
- }
- }
- /**
- * [url=home.php?mod=space&uid=247401]@brief[/url] exint0 interrupt handler
- * @param none
- * @retval none
- */
- void EXINT4_IRQHandler(void)
- {
- button_B4_isr();
- }
- void EXINT9_5_IRQHandler(void)
- {
- button_B5_isr();
- button_B7_isr();
- }
- void EXINT15_10_IRQHandler(void)
- {
- button_B10_isr();
- }
- void disp_static(void)
- {
- u8 i;
-
- for(i=0; i<5; i++) WriteHZ16((u8)(i*16+24), 0,i); //在第1行,显示汉字“科学小火箭”
- for(i=5; i<7; i++) WriteHZ16((u8)((i-5)*16),2,i); //在第2行,显示汉字“设置”
- for(i=9; i<11; i++) WriteHZ16((u8)((i-7)*16),2,i); //在第2行,显示汉字“温度”
-
- WriteHZ16((u8)(7*16),2,13); //在第2行末尾,显示“℃”
- WriteHZ16((u8)(7*16),4,13); //在第3行末尾,显示“℃”
-
- for(i=7; i<11; i++) WriteHZ16((u8)((i-7)*16),4,i); //在第3行,显示汉字“当前温度”
-
- WriteHZ16(0,6,11); //在第4行,显示汉字“第”
- WriteHZ16(48,6,12); //在第4行,显示汉字“天”
- }
- static void gpio_config(void)
- {
- gpio_init_type gpio_initstructure;
- crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
- gpio_default_para_init(&gpio_initstructure);
- /* 1. 配置ADC引脚(PA1)为模拟输入模式 */
- gpio_initstructure.gpio_mode = GPIO_MODE_ANALOG;
- gpio_initstructure.gpio_pins = GPIO_PINS_1;
- gpio_init(GPIOA, &gpio_initstructure);
-
- /* 2. 配置PA6为推挽输出模式 */
- gpio_default_para_init(&gpio_initstructure); // 重新初始化结构体
- gpio_initstructure.gpio_pins = GPIO_PINS_6;
- gpio_initstructure.gpio_mode = GPIO_MODE_OUTPUT;
- gpio_initstructure.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
- gpio_initstructure.gpio_pull = GPIO_PULL_NONE;
- gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init(GPIOA, &gpio_initstructure);
-
- // 可选:初始化PA6为低电平
- gpio_bits_reset(GPIOA, GPIO_PINS_6);
-
- }
- static void adc_config(void)
- {
- adc_common_config_type adc_common_struct;
- adc_base_config_type adc_base_struct;
- crm_periph_clock_enable(CRM_ADC2_PERIPH_CLOCK, TRUE);
- adc_common_default_para_init(&adc_common_struct);
- /* config combine mode */
- adc_common_struct.combine_mode = ADC_INDEPENDENT_MODE;
- /* config division,adcclk is division by hclk */
- adc_common_struct.div = ADC_HCLK_DIV_6;
- /* config common dma mode,it's not useful in independent mode */
- adc_common_struct.common_dma_mode = ADC_COMMON_DMAMODE_DISABLE;
- /* config common dma request repeat */
- adc_common_struct.common_dma_request_repeat_state = FALSE;
- /* config adjacent adc sampling interval,it's useful for ordinary shifting mode */
- adc_common_struct.sampling_interval = ADC_SAMPLING_INTERVAL_4CYCLES;
- /* config inner temperature sensor and vintrv */
- adc_common_struct.tempervintrv_state = FALSE;
- adc_common_config(&adc_common_struct);
- adc_base_default_para_init(&adc_base_struct);
- adc_base_struct.sequence_mode = TRUE;
- adc_base_struct.repeat_mode = FALSE;
- adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
- adc_base_struct.ordinary_channel_length = 1;
- adc_base_config(ADC2, &adc_base_struct);
- adc_resolution_set(ADC2, ADC_RESOLUTION_12B);
- /* config ordinary channel */
- adc_ordinary_channel_set(ADC2, ADC_CHANNEL_1, 1, ADC_SAMPLETIME_239_5);
- /* adc enable */
- adc_enable(ADC2, TRUE);
- while(adc_flag_get(ADC2, ADC_RDY_FLAG) == RESET);
- /* adc calibration */
- adc_calibration_init(ADC2);
- while(adc_calibration_init_status_get(ADC2));
- adc_calibration_start(ADC2);
- while(adc_calibration_status_get(ADC2));
- }
- /**
- * @brief main function.
- * @param none
- * @retval none
- */
- float target_temperature = 37.8;
- float current_temperature = 0;
- u8 target_temperature_string[5];//存储目标温度字符串
- u8 current_temperature_string[5];//存储当前温度字符串
- u8 day_s[3]; //存储天数字符串
- u8 adc_temp[5];
- u16 adc_result=0;
- float Rval;
- int time_ms =0;
- int time_s =50;
- int time_min =59;
- int time_hour=23;
- int time_days=5;
- int flag_s = 0;
- u8 time_char[9]="12:23:45";//用于存储显示用的 时:分:秒
- crm_clocks_freq_type crm_clocks_freq_struct = {0};
- int main(void)
- {
- system_clock_config();
- at32_board_init();
- button_exint_init();
- gpio_config();
- adc_config();
- hi2cx.i2cx = I2Cx_PORT;
- i2c_config(&hi2cx);
-
- uart_print_init(115200);
- printf("at32 mcu initialize ok.\r\n");
- Initialize_OLED();
- disp_static();
-
- /* get system clock */
- crm_clocks_freq_get(&crm_clocks_freq_struct);
- /* enable tmr1 clock */
- crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
- /* tmr1 configuration */
- /* time base configuration */
- tmr_base_init(TMR1, 999, (crm_clocks_freq_struct.apb2_freq / 1000000) - 1);
- tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);
- /* overflow interrupt enable */
- tmr_interrupt_enable(TMR1, TMR_OVF_INT, TRUE);
- /* tmr1 hall interrupt nvic init */
- nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
- nvic_irq_enable(TMR1_OVF_TMR10_IRQn, 1, 0);
- /* enable tmr1 */
- tmr_counter_enable(TMR1, TRUE);
- while(1)
- {
- // at32_led_toggle(LED2);
- // delay_ms(g_speed * DELAY);
- // at32_led_toggle(LED3);
- // delay_ms(g_speed * DELAY);
- // at32_led_toggle(LED4);
- // delay_ms(g_speed * DELAY);
-
- if(ioIndex==0x01)
- {
- time_days--;
- if(time_days<=0) time_days=0;
- ioIndex=0x00;
- }
-
- if(ioIndex==0x02)
- {
- time_days++;
- if(time_days>=50) time_days=0;
- ioIndex=0x00;
- }
-
- if(ioIndex==0x03)
- {
- target_temperature=target_temperature - 0.1;
- ioIndex=0x00;
- }
-
- if(ioIndex==0x04)
- {
- target_temperature=target_temperature + 0.1;
- ioIndex=0x00;
- }
- if(target_temperature>40.5) target_temperature=37.9;
- if(target_temperature<32.0) target_temperature=37.8;
-
- //计算当前温度
- adc_ordinary_software_trigger_enable(ADC2, TRUE);
- while(!adc_flag_get(ADC2, ADC_OCCE_FLAG));
- adc_flag_clear(ADC2, ADC_OCCE_FLAG);
- adc_result = adc_ordinary_conversion_data_get(ADC2);
-
- Rval=(adc_result*6200.0)/(4095.0-adc_result);
- current_temperature = Res_to_Tem(Rval);
- if(current_temperature>= 99.0) current_temperature = 99.0;
- if(current_temperature<=-30.0) current_temperature = -30.0;
-
- //简单粗暴,如果温度低于目标温度就加温否则就不加温
- if(current_temperature<target_temperature)
- {
- gpio_bits_set(GPIOA, GPIO_PINS_6);
- }
- else
- {
- gpio_bits_reset(GPIOA, GPIO_PINS_6);
- }
-
- if(flag_s)
- {
- flag_s=0;
-
- sprintf((char*)target_temperature_string, "%2.1f", target_temperature); // 格式化为保留一位小数的字符串
- sprintf((char*)current_temperature_string, "%2.1f", current_temperature); // 格式化为保留一位小数的字符串
- sprintf((char*)day_s, "%02d", time_days);
- sprintf((char*)time_char,"%02d:%02d:%02d",time_hour,time_min,time_s);
- sprintf((char*)adc_temp, "%04d", adc_ordinary_conversion_data_get(ADC2));
-
- printf_ASCII_16_text(64+8,2,target_temperature_string); //在第2行,显示设置的目标温度数值
- printf_ASCII_16_text(64+8,4," ");
- printf_ASCII_16_text(64+8,4,current_temperature_string); //在第3行,显示当前采集的温度数值
- printf_ASCII_16_text(64,6,time_char); //在第4行,显示“时分秒”
- // printf_ASCII_16_text(64+16,6,adc_temp); //在第4行,显示ADC测试值
- printf_ASCII_16_text(24,6,day_s); //在第4行,显示天数
- // FillAll(0);
- }
-
- }
- }
- void TMR1_OVF_TMR10_IRQHandler(void)
- {
- if(tmr_interrupt_flag_get(TMR1, TMR_OVF_FLAG) == SET)
- {
- time_ms++;
- if(time_ms>=1000)
- {
- time_ms=0;
- time_s++;
- flag_s=1;//用于动态刷新,每秒1次
- if(time_s>=60)
- {
- time_s=0;
- time_min++;
- if(time_min>=60)
- {
- time_min=0;
- time_hour++;
- if(time_hour>=24)
- {
- time_hour=0;
- time_days++;
- if(time_days>99) time_days=0;
- }
- }
- }
- }
- tmr_flag_clear(TMR1, TMR_OVF_FLAG);
- }
- }
- void i2c_lowlevel_init(i2c_handle_type* hi2c)
- {
- gpio_init_type gpio_init_structure;
- if(hi2c->i2cx == I2Cx_PORT)
- {
- crm_periph_clock_enable(I2Cx_CLK, TRUE);
- crm_periph_clock_enable(I2Cx_SCL_GPIO_CLK, TRUE);
- crm_periph_clock_enable(I2Cx_SDA_GPIO_CLK, TRUE);
- gpio_pin_mux_config(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_GPIO_PinsSource, I2Cx_SCL_GPIO_MUX);
- gpio_pin_mux_config(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_GPIO_PinsSource, I2Cx_SDA_GPIO_MUX);
- gpio_init_structure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
- gpio_init_structure.gpio_mode = GPIO_MODE_MUX;
- gpio_init_structure.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN;
- gpio_init_structure.gpio_pull = GPIO_PULL_UP;
- gpio_init_structure.gpio_pins = I2Cx_SCL_GPIO_PIN;
- gpio_init(I2Cx_SCL_GPIO_PORT, &gpio_init_structure);
- gpio_init_structure.gpio_pins = I2Cx_SDA_GPIO_PIN;
- gpio_init(I2Cx_SDA_GPIO_PORT, &gpio_init_structure);
- i2c_init(hi2c->i2cx, 0x0F, I2Cx_CLKCTRL);
- }
- }
测试视频
https://www.bilibili.com/video/BV1u6MvzHEQR?t=2.4
官方 的库函数有点多,需要配合手册才好理解。另外PWM也非常好用,需要慢慢掌握外设的配置方式和官方的库函数使用方法。