📄 scr.c
字号:
#include <avr/io.h>
#include <util/delay.h>
//宏定义*********************************************************************************************
//端口A,只用低四位,根据需要改
#define Set_RData() DDRA=0xFB //读(输入)
#define Set_WData() DDRA=0xFF //写(输出)
#define LCD PORTA
//PA3 模组片选端 :高电平有效
#define cS_0() LCD&=0xF7 //PA3=1111-0111 模组片选端 :高电平有效
#define cS_1() LCD|=~0xF7
//PA2 串行数据端
#define SID_0() LCD&=0xFB //PA2=1111-1011 串行数据输入端
#define SID_1() LCD|=~0xFB
//PA1 串行同步时钟,上升沿时读取SID数据
#define CLK_0() LCD&=0xFD //PA1=1111-1101 串行同步时钟,上升沿时读取SID数据
#define CLK_1() LCD|=~0xFD
//PA0,液晶复位,低电平有效
#define RET_0() LCD&=0xFE //PA0=1111-1110 低电平有效
#define RET_1() LCD|=~0xFE
//串行数据传送的第一个字节 ____ 串口控制
#define busy 0x80 //忙
#define _rdata_ 0xFE //读数据
#define _rcomm_ 0xFC //读指令
#define _wdata_ 0xFA //写数据
#define _wcomm_ 0xF8 //写指令
#define disp_star_line 0xc0 //显示起始行(后6位表示0-63行)
#define page_addr_set 0xB8 //页地址设置(后3位表示0~7页)
#define col_addr_set 0x40 //列地址设置(后6位表示0-63列)
//全局变量*****************************************************************************************
unsigned int count =0 ;
//向LCD发送一个字节******************************************************************************
void sendbyte(unsigned char senddata)
{
int i=0,j=0;
Set_WData(); //数据输出,DDRA=0XFF; 设置端口A为写(输出)
cS_1(); //模组片选端有效
CLK_0(); //时钟设低电平,以便产生上升沿
for(i=0;i<8;i++) //八位
{
if(senddata&0x80) //从高到低将数据传送到LCD,如果该位是1则SID置1,否则SID置0
SID_1();
else
SID_0();
_delay_ms(0.0001); //延时
CLK_1(); //上升沿读取SID数据写到LCD
senddata<<=1; //数据左移一位
CLK_0(); //时钟设低电平
_delay_ms(0.0001);
}
cS_0(); //片选无效
}
//从LCD读一个字节**********************************************************************************
//参数 readtype 指明所要读的数据是"指令数据"还是"显示数据"
unsigned char readByte(unsigned char readtype)
{
int i=0;
Set_WData(); //数据输出
sendbyte(readtype); //告诉LCD读什么样的数据
cS_1(); //模组片选端有效
CLK_0(); //低电平,以便产生上升沿
//DDRA&=0xFB; // set SID(PA2) input,others ouput
Set_RData();
unsigned char temph=0,templ=0,temp=0;
for(i=0;i<7;i++) //读高四位
{
CLK_1(); //上升沿,读一位
_delay_ms(1);
if(PINA&0x04)
temph=temph|1;
temph<<=1; //存到temph中
CLK_0();
_delay_ms(1);
}
CLK_1(); //上升沿,读一位
CLK_0();
for(i=0;i<7;i++) //读低四位
{
CLK_1();
_delay_ms(1);
if(PINA&0x04)
templ=templ|1;
templ<<=1; //存到templ中
CLK_0();
_delay_ms(1);
}
CLK_1(); //上升沿,读一位
temp=(temph&0xf0)|((templ&0xf0)>>4); //存到temp中
Set_WData(); // GPDIR 的CS,SID,SCLK为输出
cS_0(); //模组片选无效
return(temp);
}
//判断忙否,直到不忙才往下运行***********************************************************************
void busywait(void)
{
unsigned char bf;
do
{
bf=readByte(_rcomm_); //读指令
}
while(bf&0x80);
}
//写入一个字节的命令******************************************************************************
//参数 command 指明所要写入LCD的命令
void wr_comm_lcd(unsigned char command)
{
//busywait(); //忙否
sendbyte(_wcomm_); //告诉LCD要写指令了
sendbyte(command&0xf0); //写指令的高四位
sendbyte((command&0x0f)<<4); //写指令的低四位
}
//写入一个字节的数据*****************************************************************************
//参数 wdata 指明所要发送的显示数据
void wr_data_lcd(unsigned char wdata)
{
//busywait(); //忙否
sendbyte(_wdata_); //告诉LCD要写数据了
sendbyte(wdata&0xF0); //写数据的高四位
sendbyte((wdata&0x0F)<<4); //写数据的低四位
}
//液晶屏幕初始化************************************************************************************
void init_lcd(void)
{
RET_0(); //复位 低电平有效
_delay_ms(1); //延时
RET_1();
Set_WData(); //写(输出)
wr_comm_lcd(0x30); //功能设置,基本指令集动作
_delay_ms(1); //延时
wr_comm_lcd(0x0c); //显示状态ON,游标OFF,反白OFF
_delay_ms(1);
wr_comm_lcd(0x01); //清除显示
_delay_ms(1);
}
//清屏********************************************************************************************
void clear_lcd(void)
{
wr_comm_lcd(0x01); //清除显示
}
//光标定位************************************************************?************************
//x表示列,y表示行,(x<=8,y<=4)
void locate_xy(unsigned int x,unsigned int y)
{
unsigned char addr;
switch(y)
{
/*水平方向X,以字节单位 垂直方向Y—以位为单位*/
case 0:addr=0x80+x%8;break;
case 1:addr=0x90+x%8;break;
case 2:addr=0x88+x%8;break;
case 3:addr=0x98+x%8;break;
default:break;
}
wr_comm_lcd(addr);
}
//写一个字节到LCD******************************************************************************
//参数 word 指明要写的数据
void w_Char(unsigned char word)
{
int x=0,y=0;
y =count/8;
y= y%4; //得到行号
x = count%8; //得到列号
if(y==0 && x==0)
{
clear_lcd(); //满屏则需清屏
}
locate_xy(x,y); //定光标位置
wr_data_lcd(word); //写数据到LCD
//count++;
}
//显示一个中文字,进行两次写一字节的操作*******************************************************
//x是列号,y是行号,word1/word1是要发送中文的前/后一字节
void w_Word(unsigned int x,unsigned int y,unsigned char word1,unsigned char word2)
{
locate_xy(x,y); //定光标位置
wr_data_lcd(word1); //写前一字节
wr_data_lcd(word2); //写后一字节
}
//显示整个中文字符数组里的文字********************************************************************
//x,y为定位坐标,pstr为操作数组
void w_strword(unsigned int x,unsigned int y,unsigned char *pstr)
{
int i=0,j=0;
unsigned int t=0;
busywait(); //忙否
while(pstr[t]!='\0')t++;
for(i=0;i<(t-1);i++)
{ j=i;
i++;
w_Word(x,y,pstr[j],pstr[i]);
x++;
if(x==8)
{
y+=1; //换行
x=0; //回车
if(y==4)
{
y=0; //已满屏
}
}
}
}
void clear_panel()
{
unsigned char yaddr=0x80;
wr_comm_lcd(0x30);
wr_comm_lcd(0x34);
for(int y=0;y<32;y++)
{
wr_comm_lcd(yaddr++);
wr_comm_lcd(0x80);
for(int x=0;x<16;x++)
{
wr_data_lcd(0x00);
}
}
yaddr=0x80;
for(int y=0;y<32;y++)
{
wr_comm_lcd(yaddr++);
wr_comm_lcd(0x88);
for(int x=0;x<16;x++)
{
wr_data_lcd(0x00);
}
}
wr_comm_lcd(0x32);
wr_comm_lcd(0x36);
}
//************---画点---********************************************
//图形点阵起始数组的地址
//画点(在液晶屏上任意一点)
//横坐标x0:0~127
//纵坐标y0:0~63
void draw_point(unsigned char x0,unsigned char y0)
{
unsigned char c;//point_data;
unsigned char page,colume,screen;
wr_comm_lcd(0x30);
wr_comm_lcd(0x34);
if(y0>=32)
screen=0x88;
else
screen=0x80;
page=y0%32;
wr_comm_lcd(page|0x80);
wr_comm_lcd(screen);
//point_data=0;
//point_data=readByte(_rdata_);
if((page+1)%10==0) wr_data_lcd(0x2b);
else wr_data_lcd(0x2a);
wr_comm_lcd(0x32);
wr_comm_lcd(0x36);
}
unsigned char templetrue=0;
void pixy()
{
unsigned int count=5;
wr_comm_lcd(0x30);
wr_comm_lcd(0x34);
wr_comm_lcd(0x80|0);
wr_comm_lcd(0x80);
wr_data_lcd(0x3f);
wr_data_lcd(0x77);
for(int i=1;i<32;i++)
{
wr_comm_lcd(0x80|i);
wr_comm_lcd(0x80);
if(i%10==0)
{
wr_data_lcd(0x23);
}
else
wr_data_lcd(0x22);
switch(i)
{
case 1: wr_data_lcd(0x45);break;
case 2: wr_data_lcd(0x75);break;
case 3: wr_data_lcd(0x55);break;
case 4: wr_data_lcd(0x77);break;
case 10: wr_data_lcd(0x77);break;
case 11: wr_data_lcd(0x45);break;
case 12: wr_data_lcd(0x75);break;
case 13: wr_data_lcd(0x15);break;
case 14: wr_data_lcd(0x77);break;
case 20: wr_data_lcd(0x57);break;
case 21: wr_data_lcd(0x55);break;
case 22: wr_data_lcd(0x55);break;
case 23: wr_data_lcd(0x75);break;
case 24: wr_data_lcd(0x17);break;
case 30: wr_data_lcd(0x77);break;
case 31: wr_data_lcd(0x15);break;
default: break;
}
}
for(int i=0;i<31;i++)
{
wr_comm_lcd(0x80|i);
wr_comm_lcd(0x88);
if((i+1)%10==0)
wr_data_lcd(0x23);
else if(i>29) wr_data_lcd(0x3e);
else
wr_data_lcd(0x22);
switch(i)
{
case 0: wr_data_lcd(0x75);break;
case 1: wr_data_lcd(0x15);break;
case 2: wr_data_lcd(0x77);break;
case 8: wr_data_lcd(0x77);break;
case 9: wr_data_lcd(0x15);break;
case 10: wr_data_lcd(0x75);break;
case 11: wr_data_lcd(0x45);break;
case 12: wr_data_lcd(0x77);break;
case 18: wr_data_lcd(0x17);break;
case 19: wr_data_lcd(0x15);break;
case 20: wr_data_lcd(0x15);break;
case 21: wr_data_lcd(0x15);break;
case 22: wr_data_lcd(0x17);break;
case 27: wr_data_lcd(0x07);break;
case 28: wr_data_lcd(0x05);break;
case 29: wr_data_lcd(0x05);break;
case 30: wr_data_lcd(0x05);break;
default: break;
}
}
wr_comm_lcd(0x80|31);
wr_comm_lcd(0x88);
wr_data_lcd(0x3e);
wr_data_lcd(0x07);
wr_comm_lcd(0x32);
wr_comm_lcd(0x36);
}
void write_Int(unsigned char t)
{
if(t/10!=0)
wr_data_lcd(t/10+48);
wr_data_lcd(t%10+48);
}
void disp_lcd()
{ int j;
pixy(); //
wr_comm_lcd(0x02);
if(templetrue<=29)
{
for(j=29;j>=29-templetrue;j--)
{
draw_point(0,j+32);
}
}
else
{
for(j=29;j>=0;j--)
{
draw_point(0,j+32);
}
for(j=31;j>=29-templetrue+31;j--)
{
draw_point(0,j);
}
}
wr_comm_lcd(0x30);
w_strword(2,0,"单位:摄氏度");
w_strword(2,1,"版本号");
wr_data_lcd(':');
wr_data_lcd('1');
w_strword(2,3,"温度");
write_Int(templetrue);
wr_comm_lcd(0x36);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -