一、指针基础
该单片机中,总内存大小为512M,其中片内216M,片外216M。指针,以字节为寻址单位。
char:1字节
int:2字节
long:4字节
定义一个指针:*P
去一个变量的地址:&P
指针也是一个变量,只不过这个变量存放的是一个地址,并且,布置直接给指针赋值
sizeof是一个常量,他返回的是一个变量的字节大小。
实例一:
#include<reg52.h>
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
void ShiftLeft(unsigned char *p);//形参是一个地址
void main()
{
unsigned int i;
unsigned char buf = 0x01;
ENLED = 0;
ADDR3 = 1;
ADDR2 = 1;
ADDR1 = 1;
ADDR0 = 0;
while(1)
{
P0 = ~buf;
for(i = 0;i<20000;i++);
ShiftLeft(&buf);//取得是buf的地址,每次左移一位,改变buf的值
if(buf == 0)
{
buf = 0x01;
}
}
}
void ShiftLeft(unsigned char *p)
{
*p = *p<<1;
}
实例二:
#include<reg52.h>
bit cmdArrived = 0;//检测上位机是否发送命令,如果发送命令,置一
unsigned char cmdIndex = 0;
unsigned char *ptrTxd;
unsigned char cntTxd = 0;
unsigned char array1[1] = {1};
unsigned char array2[2] = {1,2};
unsigned char array3[4] = {1,2,3,4};
unsigned char array4[8] = {1,2,3,4,5,6,7,8};
void ConfigUART(unsigned int baud);
void main()
{
EA = 1;//使能总中断
ConfigUART(9600);
while(1)
{
if(cmdArrived)//检测到上位机发送消息
{
cmdArrived = 0;
switch(cmdIndex)
{
case 1:
ptrTxd = array1;
cntTxd = sizeof(array1);
TI = 1; //发送完毕
break;
case 2:
ptrTxd = array2;
cntTxd = sizeof(array2);
TI = 1;
break;
case 3:
ptrTxd = array3;
cntTxd = sizeof(array3);
TI = 1;
break;
case 4:
ptrTxd = array4;
cntTxd = sizeof(array4);
TI = 1;
break;
default:
break;
}
}
}
}
void ConfigUART(unsigned int baud)
{
SCON = 0x50; //配置串口为模式1
TMOD &= 0x0F; //清零T1的控制位
TMOD |= 0x20; //配置T1为模式2
TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值
TL1 = TH1; //初值等于重载值
ET1 = 0; //禁止T1中断
ES = 1; //使能串口中断
TR1 = 1; //启动T1
}
void InterruptUART() interrupt 4
{
if(RI)//如果接收完毕
{
RI = 0;
cmdIndex = SBUF;//索引号
cmdArrived = 1;
}
if(TI)//发送完毕
{
TI = 0;
if(cntTxd > 0)
{
SBUF = *ptrTxd;
cntTxd--;
ptrTxd++;//发送下一个元素
}
}
}
二、字符数组和字符指针
字符串常量“a”比字符常量‘a’多一个空值\0,即多了一个字节。
三、1602液晶
#include<reg52.h>
#define LCD1602_DB P0
sbit LCD1602_RS = P1^0;//数据指令控制位
sbit LCD1602_RW = P1^1;//读写控制位
sbit LCD1602_E = P1^5;//使能位
void InitLcd1602();
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);
void main()
{
unsigned char str[] = "Kingst Studio";
InitLcd1602();
LcdShowStr(2, 0, str);
LcdShowStr(0, 1, "Welcome to KST51");
while(1);
}
void LcdWaitReady() //读状态
{
unsigned char sta;
LCD1602_DB = 0xFF;//读之前保证是高电平
LCD1602_RS = 0;//数据模式
LCD1602_RW = 1;//读模式
do {
LCD1602_E = 1;
sta = LCD1602_DB;//将LCD的状态传递给sta
LCD1602_E = 0;//为了不影响其他外设,关闭使能位
}while(sta & 0x80);//当最高位为1时,表示LCD忙,无法进行操作
}
void LcdWriteCmd(unsigned char cmd) //写指令
{
LcdWaitReady();//判断是否可以进行读写操作
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;//数据写入
LCD1602_E = 1;//开始写入
LCD1602_E = 0;//写入关闭
}
void LcdWriteDat(unsigned char dat)//写数据
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;//数据写入
LCD1602_E = 1;
LCD1602_E = 0;
}
void LcdSetCursor(unsigned char x,unsigned char y)//显示坐标设置
{
unsigned char addr;
if(y == 0)//在第一行
{
addr = 0x00 + x;
}
else//在第二行
{
addr = 0x40 + x;
}
LcdWriteCmd(addr | 0x80);
}
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)
{
LcdSetCursor(x,y);
while(*str != '\0')
{
LcdWriteDat(*str++);
}
}
void InitLcd1602() //Lcd初始化
{
LcdWriteCmd(0x38);
LcdWriteCmd(0x0C);
LcdWriteCmd(0x06);
LcdWriteCmd(0x01);
}
总结:
在该项目中,写函数的时候自顶向下进行编写,分成不同的模块,模块之间相互调用。