#include "includes.h" //包含所需的头文件
//DQ对应引脚 GPB4
#define DQ_STATE DrvGPIO_GetBit(E_GPB,4) //DQ引脚的状态
#define CLR_DQ DrvGPIO_ClrBit(E_GPB, 4) //DQ引脚输出低电平
#define SET_DQ DrvGPIO_SetBit(E_GPB, 4) //DQ引脚输出高电平
#define DQ_OUTPUT DrvGPIO_Open(E_GPB, 4, E_IO_OUTPUT) //DQ引脚设置为输出
#define DQ_INPUT DrvGPIO_Open(E_GPB, 4, E_IO_INPUT) //DQ引脚设置为输入 一边读取该引脚的状态
/*************************************************************************************
** Function name: Set_System
** Descriptions: 1ms(晶振为12MHZ)延时子程序
** input parameters: count
** output parameters: 无
** Returned value: 无
*************************************************************************************/
void Set_System(void)
{
RCC_Configuration(); //配置系统时钟
GPIO_Configuration(); //配置GPIO
TIMER_Configuration(); //配置TIMER
}
/*************************************************************************************
** Function name: RCC_Configuration
** Descriptions: 系统时钟源设置
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
void RCC_Configuration(void)
{
UNLOCKREG(); // 对写保护位操作时 需要一次向0x50000 0100写入 0x59,0x16,0x88,
DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);//与其 SYSCLK->WRCON.XTL12M_EN = 1; 等同
// PWRCON寄存器(这些寄存器在上电复位到用户解锁定之前是锁定的)除了 BIT[6]位其他位都受写保护
// 解除这些需要向 0x50000 0100写入 0x59,0x16,0x88,
// 令PWRCON寄存器的BITP[0]为1(即设定12M外部晶振)
delay_ms(100); //while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);//等待外部12MHZ晶振就绪
LOCKREG(); // 向“0x5000_0100”写入任何值,就可以重锁保护寄存器
}
/*************************************************************************************
** Function name: GPIO_Configuration
** Descriptions: GPIO配置
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
void GPIO_Configuration()
{
DrvGPIO_Open( E_GPA, 2, E_IO_OUTPUT );//数码管段选
DrvGPIO_Open( E_GPA, 3, E_IO_OUTPUT );
DrvGPIO_Open( E_GPA, 4, E_IO_OUTPUT );
DrvGPIO_Open( E_GPA, 5, E_IO_OUTPUT );
DrvGPIO_Open( E_GPA, 6, E_IO_OUTPUT );
DrvGPIO_Open( E_GPA, 7, E_IO_OUTPUT );
DrvGPIO_Open( E_GPA, 8, E_IO_OUTPUT );
DrvGPIO_Open( E_GPA, 9, E_IO_OUTPUT );
DrvGPIO_Open( E_GPC, 14, E_IO_OUTPUT );//数码管位选
DrvGPIO_Open( E_GPC, 15, E_IO_OUTPUT );
DrvGPIO_Open( E_GPC, 6, E_IO_OUTPUT );
DrvGPIO_Open( E_GPC, 7, E_IO_OUTPUT );
}
/*************************************************************************************
** Function name: TIMER_Configuration
** Descriptions: TIMER配置
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
void TIMER_Configuration()
{
DrvTIMER_Init(); //初始化定时器
DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC, 0); //使用外设时注意必须设置该外设的时钟 设置TIMER的时钟源为外部12MHZ
DrvTIMER_Open(E_TMR0,1000,E_PERIODIC_MODE); //设定定时器 tick 周期并且启动定时器:定时器通道 TMR0 每秒1000次 周期模式
DrvTIMER_SetTimerEvent(E_TMR0,5,(TIMER_CALLBACK) Timer0_Callback,0); //安装一个定时处理事件到 timer0, timer1, timer2, timer3通道
DrvTIMER_EnableInt(E_TMR0); //使能定时器中断
DrvTIMER_Start(E_TMR0); //定时器timer0开始计数
}
/*************************************************************************************
** Function name: Timer0_Callback
** Descriptions: 定时处理事件
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
void Timer0_Callback (void)
{
static uint8_t count= 0;
static uint8_t i,xx[4];
uint32_t data;
uint16_t ValueBuff ;
ValueBuff = value*10;
count++;
if(count >= 5)
count = 1;
for(i=0;i<4;i++)
{
xx = ValueBuff%10;
ValueBuff = ValueBuff/10;
}
switch(count)
{
case 1:
DrvGPIO_SetBit(E_GPC,14);
DrvGPIO_ClrBit(E_GPC,15);
DrvGPIO_ClrBit(E_GPC,6);
DrvGPIO_ClrBit(E_GPC,7);
data= 0xC6 ; //显示C
data =data <<2;
GPIOA->DOUT = data;
break;
case 2:
DrvGPIO_SetBit(E_GPC,15);
DrvGPIO_ClrBit(E_GPC,14);
DrvGPIO_ClrBit(E_GPC,6);
DrvGPIO_ClrBit(E_GPC,7);
data = Table[xx[1]]<<2;
GPIOA->DOUT = data;
break;
case 3:
DrvGPIO_SetBit(E_GPC,7);
DrvGPIO_ClrBit(E_GPC,14);
DrvGPIO_ClrBit(E_GPC,15);
DrvGPIO_ClrBit(E_GPC,6);
data = Table[xx[2]]<<2;
GPIOA->DOUT = data;
DrvGPIO_ClrBit(E_GPA,9); //显示小数点
break;
case 4:
DrvGPIO_SetBit(E_GPC,6);
DrvGPIO_ClrBit(E_GPC,14);
DrvGPIO_ClrBit(E_GPC,15);
DrvGPIO_ClrBit(E_GPC,7);
data = Table[xx[3]]<<2;
GPIOA->DOUT = data;
break;
default:break;
}
}
/*************************************************************************************
** Function name: ds1820reset
** Descriptions: DS18B20初始化
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
void ds1820reset()
{
/*step1:首先主机产生RESET脉冲*/
DQ_OUTPUT; //将DQ引脚设置为输出
CLR_DQ; //DQ引脚输出低电平(即拉低至少为480us)
delay_ds18b20(300); //精确延时 大于480us
SET_DQ; //DQ引脚输出高电平(即释放数据线)
/*step2:等待15~60us后 DS18B20将把数据线拉低60~240us 以作为应答*/
DQ_INPUT; //将DQ引脚设置为输入
while(DQ_STATE); //如果没有应答也一直等待(注意在while里可加上超时处理 以免通信出错 而造成死机)
while(!DQ_STATE); //应答后等待(注意在while里可加上超时处理 以免通信出错 而造成死机)
/*step3:释放数据线,并延时480us(因为等待与应答必须大于480us才算整个初始化完成)*/
SET_DQ; //DQ引脚输出高电平(即释放数据线)
delay_ds18b20(300); //为了保证初始化完成 在延时480us
}
/*************************************************************************************
** Function name: ds1820rd
** Descriptions: DS18B20 读数据
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
uint8_t ds1820rd()//读数据
{
uint8_t i=0;
uint8_t dat = 0;
for (i=8;i>0;i--)
{
DQ_OUTPUT;//将DQ引脚设置为输出
CLR_DQ;//DQ引脚输出低电平(即拉低)
delay_ds18b20(2);
dat>>=1;
SET_DQ;//DQ引脚输出高电平
DQ_INPUT;//将DQ引脚设置为输入
delay_ds18b20(2);
if(DQ_STATE)
dat|=0x80;
delay_ds18b20(40);//大于60us
}
DQ_OUTPUT;
SET_DQ; //放数据线
return(dat);
}
/*************************************************************************************
** Function name: ds1820rd
** Descriptions: DS18B20 写数据
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
void ds1820wr(uint8_t wdata)//写数据
{
uint8_t i=0;
for (i=8; i>0; i--)
{
DQ_OUTPUT; //将DQ引脚设置为输出
CLR_DQ; //DQ引脚输出低电平(小于15us )
delay_ds18b20(2); //延时小于15us
if(wdata&0x01) SET_DQ; //DQ引脚输出高电平
else CLR_DQ; //DQ引脚输出低电平
delay_ds18b20(40); //延时大于60us
SET_DQ; //DQ引脚输出高电平
wdata>>=1;
}
}
/*************************************************************************************
** Function name: read_temp
** Descriptions: 读取温度值并将读到的温度进行处理
** input parameters: none
** output parameters: none
** Returned value: none
*************************************************************************************/
uint16_t read_temp()//读取温度值并转换
{
uint8_t a,b;
temp_value = 0;
ds1820reset();
ds1820wr(0xcc);//跳过读序列号
ds1820wr(0x44);//启动温度转换
ds1820reset();
ds1820wr(0xcc);//跳过读序列号
ds1820wr(0xbe);//读取温度
a=ds1820rd();
b=ds1820rd();
temp_value=b;
temp_value<<=8;
temp_value=temp_value|a;
if(temp_value<0x0fff) //如果为正数
mark=0;
else //如果为负数
{
temp_value=~temp_value+1;
mark=1;
}
temp_value=temp_value*(0.625);//温度值扩大10倍,精确到1位小数
return(temp_value);
}
/*************************************************************************************
** Function name: delay_ms
** Descriptions: 1ms(晶振为12MHZ)延时子程序
** input parameters: count
** output parameters: 无
** Returned value: 无
*************************************************************************************/
void delay_ms(uint32_t count)
{
uint32_t i,j;
for(i=count;i>0;i--)
for(j=2395;j>0;j--);
}
/*************************************************************************************
** Function name: delay_ms
** Descriptions: 大约40us(晶振为12MHZ)延时子程序
** input parameters: count
** output parameters: 无
** Returned value: 无
*************************************************************************************/
void delay_ds18b20(uint32_t count)
{
uint32_t i,j;
for(i=count;i>0;i--)
for(j=2;j>0;j--);
}
hw_config头文件