⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 STM8S105S4程序
💻 C
字号:
/******************** 2011电子科技协会 ********************
;名称 :1602液晶屏显示温度    
;作者 : 郑品洪
;日期 : 07/25/2011
;描述 : 利用1602显示实时温度
;说明 :由于stm8IO口作为输出还是输入都要进行设置,而18B20 既需要输出又需要输入,查询资料上说把
				IO口设置为开漏输出并外面加上拉电阻,我尝试过,但没有成功,所以这里采用输入输出来回切换的方法
				,因此,此程序仅作参考。  阅读此程序时请参考18B20资 料  
;***********************************************************/
#include <stm8s105s4.h>
#define uchar unsigned char
#define uint unsigned int
_Bool RS @PA_ODR:4;
_Bool RW @PA_ODR:5;           //定义1602和18B20IO口
_Bool E @PA_ODR:6;
_Bool DQ @PG_ODR:1;

uchar temp,q,a[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0x7f};
void init_Ds18B20(void);
void delay(uchar);
void delay_1ms(uint);
void write_byte(uchar);
uchar read_byte(void);
void readtemperature(void);
void display1(void);
/*********************************/
uchar table0[]="The temperature";
uchar table1[]="is:";
uchar table2[8];
uchar i;

void init_stm8(void)
{
		PA_DDR=0x70;
    PA_CR1=0x70;
    PA_CR2=0x00;
    
    PB_DDR=0xff;
    PB_CR1=0xff;
    PB_CR2=0x00;
        
  /*  PG_DDR=0x02;
    PG_CR1=0x00;            //尝试把IO口设为开漏输出,未成功
    PG_CR2=0x00;  */

	  CLK_SWR = 0xE1;      
    CLK_CKDIVR = 0x19;    //频率设为1MHz
}

//1602写指令函数,请参考“1602”的程序
void write_com(uchar com)
{
    RS=0;
    RW=0;
    PB_ODR=com;
    delay_1ms(5);
    E=1;
    E=0;	
}
//1602写数据函数, 请参考“1602”的程序
void write_data(uchar date)
{
    RS=1;
    RW=0;
    PB_ODR=date;
    delay_1ms(5);
    E=1;
    E=0;	
}
//1602初始化函数
void init(void)
{
    write_com(0x38);
    write_com(0x0c);
    write_com(0x06);
    write_com(0x01);
    write_com(0x80+0x00);	
}
//显示子函数
void display(uchar *s)         
{  
    while(*s>0)
   { 
       write_data(*s++);
    delay_1ms(90);
   }
}
/**********************************/
void main()
{ 
		init_stm8();
    init();            //初始化1602
    init_Ds18B20();    //初始化18B20
    write_byte(0xcc);
    write_byte(0x44);
    delay(300);
    display(table0);
    write_com(0x80+0x40+0x02);
    display(table1);            //以上语句为显示字符"The temperature is:"
     while(1)
     {
        readtemperature();        //读温度数据
        write_com(0x80+0x40+0x05);  //把1602地址指针指向第二行第6列
        for(i=0;i<8;i++)            //显示温度数据,包括一个正负温度符号位,一个小数点,四个数据,还有两位显示℃
    	{
            write_data(table2[i]);
    	}
     }
}
//延时一条指令子函数,用于18B20时序操作
void delay(uchar t)
{
    while(t--);
}

void delay_1ms(uint a)
{
    char i;
    while(a--)
    for(i=0;i<120;i++);
}
//18B20初始化函数
void init_Ds18B20(void)
{
		uchar n;
			
	  PG_DDR=0x02;
    PG_CR1=0x02;   //设置IO口为推挽输出模式
    PG_CR2=0x00;
	
    DQ=1;
    delay(2);
    DQ=0;
    delay(200);
    DQ=1;
    delay(50);
    n=DQ;
    delay(100);    //以上语句为检查是否存在18B20,若n=0说明 18B20存在
}
//18B20写子函数
void write_byte(uchar date)
{
    uchar i;
		
		PG_DDR=0x02;
    PG_CR1=0x02;   //设置IO口为推挽输出
    PG_CR2=0x00;
		
		delay_1ms(2);
    for(i=0;i<8;i++)  //请参考18B20时序图
    {
			 DQ=0;
       delay(1);
       DQ=date&0x01;
       delay(10);
       DQ=1;
       date>>=1;
    }
    delay(4);
}
//18B20读子函数
uchar read_byte(void)
{
    uchar i,value;
		delay_1ms(2);
    for(i=0;i<8;i++)
    {
			  PG_DDR=0x02;
        PG_CR1=0x02;    //设置IO口为推挽输出
        PG_CR2=0x00; 
				
        DQ=0;
        value>>=1;     //先读地位,因此没读一次数向左移动 一位
        DQ=1; 
				
		    PG_DDR=0x00;
        PG_CR1=0x02;   //读数据时设置IO口为上拉输入
        PG_CR2=0x00;
				
        if((PG_IDR&0x02)==0x02)  //如果IO口电压为高,则value中对应的位为1,否则为0
        value|=0x80;
        delay(4);
    } 
    return value;            //将读的数返回
}
//读温度数据并处理子函数
void readtemperature(void)
{
    uchar a,b,p;		
		init_Ds18B20();     //初始化18B20
    write_byte(0xcc);   //逃过ROM,一个IO口有多个 18B20时需 要读ROM
    write_byte(0x44);   //启动温度检测
    DQ=1;
    delay(200);         //延时,等待温度检测完成
		init_Ds18B20();     //每次操作前要初始化18B20
		write_byte(0xcc);   //跳过ROM
    write_byte(0xbe);   //从储存器读数据
    a=read_byte();      //读地位温度数据
    b=read_byte();      //读高位温度数据
		if(b>0x07)          //如果温度为负数,b会大于0x07,故当b大于0x07时,让1602在温度前面显示“-”
		  q=1;
    p=(a&0x0f)*625/100;  //小数部分数据处理,由于小数部分有 四位,故分辨率为1/16,16×625刚好为10000,这里再除于100是精确到小数点后两位
		                     //理论上18B20可以精确到小数点后四位,但由于分辨率只有1/16,即0.06左右,小数点后第三第四位已经没有实际意义
    b=(b<<4)+(a>>4);     //将低位温度数据的高四位和高位温度 数据的 低四位拼成温度数据的整数部分
		
    table2[7]=0x43;      //摄氏度中“C” 的代码
    table2[6]=0xdf;      //摄氏度中“。“ 的代码
    table2[5]=p%10+0x30;  //小数点后第二位数据,加上30是为了和1602中字符代码一致
    table2[4]=p/10+0x30;
    table2[3]=0x2e;       //小数点代码
    table2[2]=b%10+0x30;  
    table2[1]=b/10+0x30;   //整数部分
		table2[0]=0x80;        //空字符代码,就是不显示任何字符
    if(q==1)               
    table2[0]=0x2d;        //”-“代码,若温度为-,则显示  
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -