最近做的小实验主要运用GD32F350作为主控MCU,通过一线式通讯接口,外接一个DS18B20进行温度采集。由于是单线式传输,因此对时序要求比较严苛。本次小实验要实现的功能比较简单,大概的执行流程就是通过DS18B20实时采集室内温度,并通过内部寄存器将模拟信号转换成数字信号,编写一线式通讯协议,使用GPIOB_12将完成数据的收发。当采集的温度值在10℃~33℃时为正常范围,显示内部LED灯为0.3秒亮灭间隔,外部7盏灯会依次以0.05秒的时间间隔亮灭。如果大于33℃或者小于10℃时,则内部LED灯以0.05秒的时间间隔依次两灭,同时外部LED的第8盏灯也会以0.3秒亮灭频率闪烁,并且外部蜂鸣器器会持续响起,用到的是GPIOC_6管脚。当然这温度的范围根据用户要求可以适时设定。
主要配置一些GPIO的代码如下:
- #include <stdio.h>
- #include "bsp_ds18b20.h"
- #include "gd32f3x0.h"
- #include "colibri_bsp.h"
- #define DS18B20_SKIP_ROM 0xcc //跳过序列号
- #define DS18B20_COVERTT 0x44 //数值转换
- #define DS18B20_READ_MEM 0xbe //读取数据
- uint32_t Tick;
- uint16_t buffer[3]={249,499,749};
- GPIO_InitPara GPIO_InitStructure;
- static volatile uint32_t uwTick;
- void systick_config(void)
- {
- /* setup systick timer for 1Mhz interrupts */
- if (SysTick_Config(SystemCoreClock / 1000000U)) while (1); //1Mhz
- /* configure the systick handler priority */
- NVIC_SetPriority(SysTick_IRQn, 0x00U);
- }
- void GD_decTick(void)
- {
- if(0U != uwTick){
- uwTick--;
- }
- }
- void delayus(uint32_t nTime)
- {
- uwTick = nTime;
- while(0U != uwTick){
- }
- }
- void delayms(uint32_t nTime)
- {
- uwTick = nTime*1000;
- while(0U != uwTick){
- }
- }
- void SysTick_Callback(void)
- {
- }
- void SysTick_Handler(void) //1Mhz
- {
- static uint32_t time =0;
- time++;
- GD_decTick();
- if(time == LOOP_TIME){ //1M/LOOP_TIME=1M/10000=100hz
- SysTick_Callback();
- time = 0;
- }
- }
- /*!
- \brief configure the TIMER peripheral
- \param[in] none
- \param[out] none
- \retval none
- */
- void timer_config(void)
- {
- /* TIMER0 DMA Transfer example -------------------------------------------------
- TIMER0CLK = 84MHz(GD32F330) or 108MHz(GD32F350), Prescaler = 84(GD32F330) or 108(GD32F350)
- TIMER0 counter clock 1MHz.
- the objective is to configure TIMER0 channel 1 to generate PWM
- signal with a frequency equal to 1KHz and a variable duty cycle(25%,50%,75%) that is
- changed by the DMA after a specific number of update DMA request.
- the number of this repetitive requests is defined by the TIMER0 repetition counter,
- each 2 update requests, the TIMER0 Channel 0 duty cycle changes to the next new
- value defined by the buffer .
- -----------------------------------------------------------------------------*/
- timer_oc_parameter_struct timer_ocintpara;
- timer_parameter_struct timer_initpara;
- rcu_periph_clock_enable(RCU_TIMER0);
- timer_deinit(TIMER0);
- /* TIMER0 configuration */
- #ifdef GD32F330
- timer_initpara.prescaler = 83;
- #endif /* GD32F330 */
- #ifdef GD32F350
- timer_initpara.prescaler = 107;
- #endif /* GD32F350 */
- timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
- timer_initpara.counterdirection = TIMER_COUNTER_UP;
- timer_initpara.period = 999;
- timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
- timer_initpara.repetitioncounter = 1;
- timer_init(TIMER0,&timer_initpara);
- /* CH0 configuration in PWM0 mode */
- timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
- timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;
- timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
- timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
- timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH;
- timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
- timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara);
- timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,buffer[0]);
- timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);
- timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
- /* TIMER0 primary output enable */
- timer_primary_output_config(TIMER0,ENABLE);
- /* TIMER0 update DMA request enable */
- timer_dma_enable(TIMER0,TIMER_DMA_UPD);
- /* auto-reload preload enable */
- timer_auto_reload_shadow_enable(TIMER0);
- /* TIMER0 counter enable */
- timer_enable(TIMER0);
- }
- void GPIO_Init(uint32_t gpio_periph,GPIO_InitPara *Para)
- {
- rcu_periph_clock_enable(RCU_GPIOB);
-
- rcu_periph_clock_enable(RCU_GPIOB);
- GPIO_BOP(gpio_periph) = Para->GPIO_Pin;
- GPIO_OSPD0(gpio_periph) = Para->GPIO_Speed;
- GPIO_OMODE(gpio_periph) = Para->GPIO_Mode;
- GPIO_BC(gpio_periph) = Para->GPIO_Pin;
- }
- void TempGPIOInit(void)
- {
- rcu_periph_clock_enable(RCU_GPIOB);
- GPIO_InitStructure.GPIO_Pin = GPIO_PIN_12;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
- }
- void TempGPIOin(void)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_PIN_12;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_IN_FLOATING;
- GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
- }
- void TempGPIOout(void)
- {
- GPIO_InitStructure.GPIO_Pin = GPIO_PIN_12;
- GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
- }
外部的蜂鸣器代码如下:
- void RunBeepExternal(unsigned int TimeCounter)
- {
- gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE,GPIO_PIN_6);
- delayus(TimeCounter);
- EvbBeepExternalControl(BEEP_ON);
- delayus(TimeCounter);
- EvbBeepExternalControl(BEEP_OFF);
- delayus(TimeCounter);
- EvbBeepExternalControl(BEEP_ON);
- delayus(TimeCounter);
- EvbBeepExternalControl(BEEP_OFF);
- delayus(TimeCounter);
- EvbBeepExternalControl(BEEP_ON);
- delayus(TimeCounter);
- EvbBeepExternalControl(BEEP_OFF);
- delayus(TimeCounter);
- }
外部蜂鸣器亮起,报警提示。
此次实验的时序很重要,对于DS18B20,我象征性的截了几张图如下:
GD32F350的正面照及硬件连接如下:
最后祝福GD32兆易创新能够越来越红火,将来举办越来越多的优惠活动,祝愿兆易创新在2019年能出更多创新型产品。最近的GD32E231也问世了,希望开发资源丰富,让工程师越来越容易上手,灵活使用。
|