最近做的小实验主要运用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也问世了,希望开发资源丰富,让工程师越来越容易上手,灵活使用。
|