51单片机如何使用指针控制IO

51单片机如何使用指针控制IO,第1张

51 单片机的 IO 接口,必须使用直接寻址方式。

所以,在 C 语言中,不可使用指针对 IO 接口进行 *** 作。

凡是必须直接寻址的,如:TMOD、IE、IP 等等,都不可使用指针。

还有位地址,也不行。

//DS从机程序

#include <reg52h>

#include <intrinsh>

#define uchar unsigned char

#define uint unsigned int

#define SLAVE 0x01

#define BN 6

sbit LCD_RS = P2^5; /定义LCD控制端口/

sbit LCD_RW = P2^6;

sbit LCD_EN = P2^7;

sbit DS1=P1^0;

sbit DS2=P1^1;

sbit key3=P3^5;

sbit tem=P3^3;

sbit win=P3^4;

sbit key1=P3^6;

sbit key2=P3^7;

uint temp1,temp2,tempH,tempL; // variable of temperature

uchar flag1,aa,we;

uchar A1,A2,A3,A4,B1,B2,B3,B4; // sign of the result positive or negative

uchar dis1[16]={76,45,84,'0','0','','0',32,32,72,45,84,'0','0','','0'};

uchar dis2[16]={48,49,32,'0','0','','0',32,32,48,50,32,'0','0','','0'};

uchar code tab[] = {'0','1','2','3','4','5','6','7','8','9'};

uchar trbuf[6];

bit tready;

bit rready;

void str(void);

void sre(void);

void delay(int ms)

{

int i;

while(ms--)

{

for(i = 0; i< 250; i++)

{

_nop_();

_nop_();

_nop_();

_nop_();

}

}

}

//

/ /

/检查LCD忙状态 /

/lcd_busy为1时,忙,等待。lcd-busy为0时,闲,可写指令与数据。 /

/ /

//

bit lcd_busy()

{

bit result;

LCD_RS = 0;

LCD_RW = 1;

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

result = (bit)(P0&0x80);

LCD_EN = 0;

return result;

}

//

/ /

/写指令数据到LCD /

/RS=L,RW=L,E=高脉冲,D0-D7=指令码。 /

/ /

//

void lcd_wcmd(uchar cmd)

{

while(lcd_busy());

LCD_RS = 0;

LCD_RW = 0;

LCD_EN = 0;

_nop_();

_nop_();

P0 = cmd;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 0;

}

//

/ /

/写显示数据到LCD /

/RS=H,RW=L,E=高脉冲,D0-D7=数据。 /

/ /

//

void lcd_wdat(uchar dat)

{

while(lcd_busy());

LCD_RS = 1;

LCD_RW = 0;

LCD_EN = 0;

P0 = dat;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 1;

_nop_();

_nop_();

_nop_();

_nop_();

LCD_EN = 0;

}

//

/ /

/ 设定显示位置 /

/ /

//

void lcd_pos(uchar pos)

{

lcd_wcmd(pos|0x80); //数据指针=80+地址变量

}

//

/ /

/ LCD初始化设定 /

/ /

//

void lcd_init()

{

lcd_wcmd(0x38); //162显示,57点阵,8位数据

delay(5);

lcd_wcmd(0x38);

delay(5);

lcd_wcmd(0x38);

delay(5);

lcd_wcmd(0x0c); //显示开,关光标

delay(5);

lcd_wcmd(0x06); //移动光标

delay(5);

lcd_wcmd(0x01); //清除LCD的显示内容

delay(5);

lcd_wcmd(0x06); //向右移动光标

delay(5);

}

//

/ /

/ 闪动子程序 /

/ /

//

void flash()

{

delay(600); //控制停留时间

lcd_wcmd(0x08); //关闭显示

delay(200); //延时

lcd_wcmd(0x0c); //开显示

delay(200); //延时

lcd_wcmd(0x08); //关闭显示

delay(200); //延时

lcd_wcmd(0x0c); //开显示

delay(200);

}

/void delay(uint count) //delay

{

uint i;

while(count)

{

i=100;

while(i>0)

i--;

count--;

}

} /

///////功能:串口初始化,波特率9600,方式1///////

void Init(void)

{

TMOD=0x20;

TL1=0xfd;

TH1=0xfd;

PCON=0x00;

TR1=1;

SCON=0xf0;

ES=1;

EA=1;

}

void dsreset(uchar DS) //send reset and initialization command 18B20复位,初始化函数

{

uint i;

if(DS==1)

{

DS1=0;

i=103;

while(i>0)i--;

DS1=1;

i=4;

while(i>0)i--;

}

if(DS==2)

{

DS2=0;

i=103;

while(i>0)i--;

DS2=1;

i=4;

while(i>0)i--;

}

}

bit tmpreadbit(uchar DS) //read a bit 读DS2 1位数据函数

{

uint i;

bit dat;

if(DS==1)

{

DS1=0;i++; //i++ for delay

DS1=1;i++;i++;

dat=DS1;

i=8;while(i>0)i--;

}

if(DS==2)

{

DS2=0;i++; //i++ for delay

DS2=1;i++;i++;

dat=DS2;

i=8;while(i>0)i--;

}

return (dat);

}

uchar tmpread(uchar DS) //read a byte date 读1字节函数

{

uchar i,j,dat;

dat=0;

if(DS==1)

{

for(i=1;i<=8;i++)

{

j=tmpreadbit(1);

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

}

if(DS==2)

{

for(i=1;i<=8;i++)

{

j=tmpreadbit(2);

dat=(j<<7)|(dat>>1); //读出的数据最低位在最前面,这样刚好一个字节在DAT里

}

}

return(dat);

}

void tmpwritebyte(uchar dat,uchar DS) //write a byte to ds18b20 向1820写一个字节数据函数

{

uint i;

uchar j;

bit testb;

for(j=1;j<=8;j++)

{

testb=dat&0x01;

dat=dat>>1;

if(DS==1)

{

if(testb) //write 1

{

DS1=0;

i++;i++;

DS1=1;

i=8;while(i>0)i--;

}

else

{

DS1=0; //write 0

i=8;while(i>0)i--;

DS1=1;

i++;i++;

}

}

if(DS==2)

{

if(testb) //write 1

{

DS2=0;

i++;i++;

DS2=1;

i=8;while(i>0)i--;

}

else

{

DS2=0; //write 0

i=8;while(i>0)i--;

DS2=1;

i++;i++;

}

}

}

}

void tmpchange(uchar DS) //DS18B20 begin change 开始获取数据并转换

{

if(DS==1)

{

dsreset(1);

delay(1);

tmpwritebyte(0xcc,1); // address all drivers on bus 写跳过读ROM指令

tmpwritebyte(0x44,1);

} // initiates a single temperature conversion 写温度转换指令

if(DS==2)

{

dsreset(2);

delay(1);

tmpwritebyte(0xcc,2); // address all drivers on bus 写跳过读ROM指令

tmpwritebyte(0x44,2);

} // initiates a single temperature conversion 写温度转换指令

}

uint tmp1(void) //get the temperature 读取寄存器中存储的温度数据

{

float tt;

uchar a,b;

dsreset(1);

delay(1);

tmpwritebyte(0xcc,1);

tmpwritebyte(0xbe,1);

a=tmpread(1); //读低8位

b=tmpread(1); //读高8位

temp1=b;

temp1<<=8; //two byte compose a int variable 两个字节组合为1个字

temp1=temp1|a;

tt=temp100625; //温度在寄存器中是12位,分辨率是00625

temp1=tt10+05; //乘10表示小数点后只取1位,加05是四折五入

//temp1=temp1+5; //误差补偿

return temp1;

}

uint tmp2( void) //get the temperature 读取寄存器中存储的温度数据

{

float tt;

uchar a,b;

dsreset(2);

delay(1);

tmpwritebyte(0xcc,2);

tmpwritebyte(0xbe,2);

a=tmpread(2); //读低8位

b=tmpread(2); //读高8位

temp2=b;

temp2<<=8; //two byte compose a int variable 两个字节组合为1个字

temp2=temp2|a;

tt=temp200625; //温度在寄存器中是12位,分辨率是00625

temp2=tt10+05; //乘10表示小数点后只取1位,加05是四折五入

//temp2=temp2+5; //误差补偿

return temp2;

}

void delay10ms() //delay

{

uchar a,b;

for(a=10;a>0;a--)

for(b=60;b>0;b--);

}

uchar display(uint temp1,uint temp2) //显示程序

{

uchar i;

A1=temp1/100;

A2=temp1%100/10;

A3=temp1%100%10;

B1=temp2/100;

B2=temp2%100/10;

B3=temp2%100%10;

trbuf[0]=A1;

trbuf[1]=A2;

trbuf[2]=A3;

trbuf[3]=B1;

trbuf[4]=B2;

trbuf[5]=B3;

dis1[3]=tab[tempL10/100];

dis1[4]=tab[tempL10%100/10];

dis1[6]=tab[tempL10%100%10];

dis1[12]=tab[tempH10/100];

dis1[13]=tab[tempH10%100/10];

dis1[15]=tab[tempH10%100%10];

dis2[3]=tab[A1];

dis2[4]=tab[A2];

dis2[6]=tab[A3];

dis2[12]=tab[B1];

dis2[13]=tab[B2];

dis2[15]=tab[B3];

delay(1);

lcd_pos(0); //设置显示位置为第一行的第1个字符

delay(2);

for(i=0;i<16;i++)

{

lcd_wdat(dis1[i]);

}

delay(2);

lcd_pos(0x40);

delay(2);

for(i=0;i<16;i++)

{

lcd_wdat(dis2[i]);

}

return (A1,A2,A3,B1,B2,B3);

}

void TemC()

{

if(temp1<=(tempL10)||temp2<=(tempL10)) tem=0;

else tem=1;

if (temp1>=(tempH10)||temp2>=(tempH10)) win=0;

else win=1;

}

uchar chan()

{

if(key1==0)

{

tempL++;

while(key1==0);

if(tempL>35)

tempL=0;

}

if(key2==0)

{

tempH++;

while(key2==0);

if(tempH>35)

tempH=0;

}

return (tempH,tempL);

}

//

void main()

{ //uchar a;

//uchar i;

delay(10);

lcd_init();

Init();

tempH=35;

tempL=15;

while(1)

{

tmpchange(1);

tmpchange(2);

tmp1();

tmp2();

chan();

TemC();

display(temp1,temp2);

tready=1;

rready=1;

}

}

void ssio(void)interrupt 4

{

uchar a;

RI=0;

ES=0;

if(SBUF!=SLAVE)

{

ES=1;

goto reti;

}

SM2=0;

SBUF=SLAVE;

while(TI!=1);

TI=0;

while(RI!=1);

RI=0;

if(RB8==1)

{

SM2=1;

ES=1;

goto reti;

}

a=SBUF;

if(a==0x02)

{

if(tready==1)

SBUF=0x02;

else

SBUF=0x00;

while(TI!=1);

TI=0;

str();

goto reti;

}

else

{

SBUF=0x08;

while(TI!=1);

TI=0;

SM2=1;

ES=1;

}

reti:RI=0;

SM2=1;

ES=1;

}

void str(void)

{

uchar i;

tready=0;

while(1)

{

tmpchange(1);

tmpchange(2);

tmp1();

tmp2();

chan();

TemC();

display(temp1,temp2);

for(i=0;i<BN;i++)

{

SBUF=trbuf[i];

while(TI!=1);

TI=0;

}

while(RI!=1);

RI=0;

if(RB8==1)goto loop;

}

loop:SM2=1;

ES=1;

}

单片机的io口设置成输出或输入状态就是给这个io口赋值为0或1。但是这个0或1并代表是输入还是输出状态,这要取决于你连接这个口的是什么器件,或者说取决于你这个口要实现的是输入还是输出状态。比如点亮一个led灯,首先一定是io口输出一个状态才能让灯亮对吧,那么给0还是给1得看电路。再比如按键,这时就是给io口输入了。是0还是1也看电路。

最后一个特殊就是ad采集,这肯定是输入吧,但是不能单纯的理解为给个0或1了。再比如pwm这肯定是输出,但也不能单纯的理解为给个0或1。

说了这么多,意思就是看你要让这个口实现的是输入还是输出状态,当你确定了,那么这个口的状态也就被确定了。

以上就是关于51单片机如何使用指针控制IO全部的内容,包括:51单片机如何使用指针控制IO、51单片机两个I/O口分别接ds18b20程序、怎样将51单片机IO口设置成输出状态或输入状态呢希望高手能给通俗易懂的解答一下!!!回答好了可以等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9688808.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存