📄 mcs51-项目开发经典.c
字号:
//=================================================================================================
// 项目名:MCS51-项目开发经典
// 硬件文件名:51Studay.DDB
// 程序组目录名:MCS51-项目开发经典
// 开始时间:2007年5月21日
// 完成时间:2007年6月10日
//-------------------------------------------------------------------------------------------------
// 程序中用到哪些C51标准函数,就需要把该函数对应的头文件包含进来
//-------------------------------------------------------------------------------------------------
#include <intrins.h>
#include <string.h>
#include <absacc.h>
#include <reg52.h>
//-------------------------------------------------------------------------------------------------
// 为提高书写效率做以下宏定义
//-------------------------------------------------------------------------------------------------
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define CLOSE 1
#define OPEN 0
//-------------------------------------------------------------------------------------------------
// 液晶模块12232C-3操控位宏定义,液晶模块内部驱动器为ST7920
//-------------------------------------------------------------------------------------------------
#define x 0x80
#define y 0x80
#define comm 0
#define dat 1
sbit cs = P2^0; //
sbit std = P2^1; //
sbit sclk = P2^2; //
sbit rs = P2^0; //H=data; L=command;
sbit rw = P2^1; //H=read; L=write;
sbit e = P2^2; //input enable;
sbit busy = P0^7; //lcd busy bit
uchar read_data_high;
uchar read_data_low;
sbit LCM_LED =P2^3;
uchar code tab1[]={"无敌男人刘宝宇!" //第一行显示内容
"杭州电子科技大!"};//第二行显示内容
uchar code tab3[]={"&&疯狂工作室!&&" //第一行显示内容
"07048055号学生!"};//第二行显示内容
uchar code Picture_kfjd[]={//图像lcm_pic_kfjd.bmp,宽度x高度=128x32
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
uchar t1_delay_time;//50毫秒计数器累加变量,在T2中断里累加
//-------------------------------------------------------------------------------------------------
// 函数声明
//-------------------------------------------------------------------------------------------------
void init_cpu(void);
void init_lcd (void);
void uart_byte_out(uchar uart_data_out);
void uart_string_out(char * char_array);
void write_lcd (uchar dat_comm,uchar content);
uchar read_lcd(void);
void check_busy (void);
void init_lcd (void);
void image_clear(void);
void lcm_clear_ram (void);
void chinese_or_character_display (uchar code *char_name);
void image_display (uchar code *img);
void line_display (uchar y_coordinate, uchar x_coordinate, uint show_data);
uint line_read (uchar y_coordinate, uchar x_coordinate);
//=================================================================================================
//===================== ================================================
//===================== 主程序 ================================================
//===================== ================================================
//=================================================================================================
void main (void)
{
uint reader;
uchar i;
init_cpu();
init_lcd ();
LCM_LED = OPEN;
uart_string_out("LCM test ok!");
lbyloop:
/* line_display (10, 0 ,0xfaaf);
reader = line_read (10, 0);
//reader = read_data_high;
//reader = (reader<<8) | read_data_low;
line_display (12, 0 ,reader);
for(t1_delay_time=0;t1_delay_time<120;);//延时10秒*/
image_clear();
chinese_or_character_display (tab1);//"
for(t1_delay_time=0;t1_delay_time<100;);//延时3秒
// for(i=0;i<8;i++)
// {
// for (t1_delay_time=0;t1_delay_time<100;t1_delay_time++) write_lcd (comm,0x18);
// }
chinese_or_character_display (tab3);//"
for(t1_delay_time=0;t1_delay_time<100;);//延时3秒
lcm_clear_ram();
goto lbyloop;
}
//########################## 主程序结束 #########################################################
//########################## 子程序开始 #########################################################
//=================================================================================================
// 函数功能:CPU初始化函数
// 串口波特率可以由T1或T2产生,本例中用T1产生波特率
// T2用于50毫秒精确定时
// T0用于PWM控制中频率的时基
//=================================================================================================
void init_cpu(void)
{
TMOD=0x12;//T1为16位计数器,T0为8位自动重装载计数器
ET1=1;
TH1=0x4c;//11.0592M晶振时T1定时时间长度为50毫秒
TL1=0x00;
TR1=1;//T1开始定时
T2CON=0x30;//定时器T2工作于波特率发生器方式
RCAP2H=0xff;//11.0592M晶振,9600bps初值
RCAP2L=0xdc;
TH2=0xff;
TL2=0xdc;
TR2=1;//允许T2中断
SCON=0x40;//串口工作于方式1,启动串口接收
EA=1;//CPU中断开放
}
//=================================================================================================
// 串口UART操作相关程序
//=================================================================================================
//函数功能:串口发射1个字节
void uart_byte_out(uchar uart_data_out)
{ SBUF = uart_data_out;
while(TI==0);
TI=0;
}
//-------------------------------------------------------------------------------------------------
//函数功能:串口发射字符数组。通常将要发送的字符数组定义在CODE代码区。
void uart_string_out(char * char_array)
{ uchar i;
for(i=0; i<strlen(char_array) ;i++)
{
uart_byte_out(char_array[i]);
}
}
// 液晶ST7920驱动程序
//=================================================================================================
//-------------------------------------------------------------------------------------------------
// 函数功能:液晶并行写数据或写指令
// 形参:dat_or_comm 区分指令或数据,由宏定义可知 comm表示指令,dat表示数据
// content 指令或数据内容
void write_lcd (uchar dat_comm,uchar content)
{
check_busy ();
if(dat_comm)
{rs=1; //data
rw=0; //write
}
else
{rs=0; //command
rw=0; //write
}
P0=content; //output data or comm
e=1;
e=0;
}
//-------------------------------------------------------------------------------------------------
uchar read_lcd (void)
{ uchar fhz;
check_busy ();
P0=0xff;
rs=1;
rw=1;
e=1;
fhz=P0;
e=0;
return(fhz) ;
}
//-------------------------------------------------------------------------------------------------
//函数功能:判断液晶忙闲
void check_busy (void)
{ uint max_delay_time=65535;
P0=0xff;
rs=0;
rw=1;
e =1;
while(busy==1)
{
max_delay_time--;//如果busy==1条件永远满足不了(如液晶损坏),则延时一段时间后退出
if(max_delay_time==0) break;
}
e =0;
}
//-------------------------------------------------------------------------------------------------
// 函数功能:液晶模块初始化
void init_lcd (void)
{
write_lcd (comm,0x30); //6 功能设定:使用基本指令动作,8位控制接口
write_lcd (comm,0x01); //1 清屏:DDRAM全部写20H,地址指针指向00H
write_lcd (comm,0x02); //2 地址归位:地址指针指向00H
write_lcd (comm,0x06); //3 点设定:置光标右移,AC自动加 1,整体显示不移动
write_lcd (comm,0x0c); //4 显示状态设定:置整体显示开,光标关,光标位置不反白闪烁
write_lcd (comm,0x14); //5 光标或显示移位控制:光标右移,AC加 1
}
//-------------------------------------------------------------------------------------------------
// 函数功能:刷新图像
void image_clear(void)
{
uchar y_zb,x_zb;
for(y_zb=0;y_zb<32;y_zb++)
{for(x_zb=0;x_zb<8;x_zb++)
{line_display (y_zb, x_zb, 0x0000);
}
}
}
//-------------------------------------------------------------------------------------------------
// 函数功能:清DDRAM
void lcm_clear_ram (void)
{
write_lcd (comm,0x30);
write_lcd (comm,0x01);
}
//-------------------------------------------------------------------------------------------------
// 函数功能:显示汉字或字符
// 12232C液晶模块的显示结构为:共2行显示,每行可显示15个字符或7个半汉字
// 显示内容可以字符和汉字混排,方法如下:
// 即一个汉字为2字节,一个字符1字节,汉字字符可以穿插,只要保证每行15字节就可正确显示
void chinese_or_character_display (uchar code *char_name)
{
uchar i;
write_lcd (comm,0x30);
write_lcd (comm,0x80);//设定DDRAM地址到地址计数器AC,即第一行显示首址
for (i=0;i<15;i++)
{write_lcd (dat,char_name[i]);//显示第一行内容,要显示字符串的0-14字节
}
write_lcd (comm,0x90);//设定DDRAM地址到地址计数器AC,即第二行显示首址
for (i=15;i<30;i++)
{write_lcd (dat,char_name[i]);//显示第二行内容,要显示字符串的15-29字节
}
}
//-------------------------------------------------------------------------------------------------
// 函数功能:显示图片
void image_display (uchar code *img)
{
uchar i,j;
for(j=0;j<32;j++)
{
for(i=0;i<8;i++)
{
write_lcd (comm,0x34);
write_lcd (comm,y+j);
write_lcd (comm,x+i);
write_lcd (comm,0x30);
write_lcd (dat,img[j*16+i*2]);
write_lcd (dat,img[j*16+i*2+1]);
}
}
write_lcd (comm,0x36);//绘图显示开
}
//-------------------------------------------------------------------------------------------------
void line_display (uchar y_coordinate, uchar x_coordinate, uint show_data)
{
uchar data_high,data_low;
data_high = (show_data & 0xff00)>>8;
data_low = show_data & 0x00ff;
write_lcd (comm,0x34);
write_lcd (comm,0x80 + y_coordinate);
write_lcd (comm,0x80 + x_coordinate);
write_lcd (comm,0x30);
write_lcd (dat,data_high);
write_lcd (dat,data_low);
write_lcd (comm,0x36);//绘图显示开
}
//-------------------------------------------------------------------------------------------------
uint line_read (uchar y_coordinate, uchar x_coordinate)
{
uchar data_high,data_low;
uint data_backup;
write_lcd (comm,0x34);
write_lcd (comm,0x80 + y_coordinate);
write_lcd (comm,0x80 + x_coordinate);
write_lcd (comm,0x30);
read_lcd ();
data_high = read_lcd ();
data_low = read_lcd ();
data_backup = data_high;
data_backup = (data_backup<<8) | data_low;
return(data_backup);
}
//=================================================================================================
// T1中断服务程序
//=================================================================================================
void T1_interrupt(void) interrupt 3
{
TH1=0x4c;//11.0592M晶振时T1定时时间长度为50毫秒
TL1=0x00;
t1_delay_time++;//在需要延时的地方清空并判断该变量
}
//=================================================================================================
// end of the file
//=================================================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -