經(jīng)過多天調(diào)式,優(yōu)化程序。只用兩個IO端口驅(qū)動74LS164擴展成并口驅(qū)動LCD1602(四線模式),這是個完整簡單的例子,可實現(xiàn)字符串左移200次,右移200次,不停的循環(huán)。現(xiàn)上傳與大家共享成果!//引入頭文件*********************************************************
#include <pic.h>
#include <pic12f6x.h>
#include "delay.h"
#include "delay.c"
//熔絲配置***********************************************************
__CONFIG(PROTECT & CPD & BOREN & MCLRDIS & PWRTEN & WDTDIS & INTIO);
//端口定義***********************************************************
#define Port GPIO //端口址址
#define Tris TRISIO //方向設(shè)置
//腳位定義***********************************************************
#define Dat GPIO4 //數(shù)據(jù)引腳
#define Clk GPIO5 //時鐘引腳
//顯示字符***********************************************************
unsigned char TopChar[] = {"www.pic16.com "}; //
unsigned char BotChar[] = {"ivws "}; //
//*******************************************************************
//函數(shù)名稱:PortInit();
//輸入?yún)?shù):無
//輸出參數(shù):無
//功能描述:端口設(shè)置
//建造日期:2008.12.08
//********************************************************************
void PortInit(void)
{
Port = 0x00; //端口設(shè)置
Tris = 0x00;
}
//*******************************************************************
//函數(shù)名稱:ConInit();
//輸入?yún)?shù):無
//輸出參數(shù):無
//功能描述:定時器設(shè)置
//建造日期:2008.12.08
//*******************************************************************
void ConInit(void)
{
OPTION = 0x00; //允許上拉
CMCON = 0x07; //關(guān)比較器
}
//*******************************************************************
//函數(shù)名稱: TxLs164(data);
//輸入?yún)?shù):串行數(shù)據(jù)
//輸出參數(shù):無
//功能描述:串行發(fā)送數(shù)據(jù)
//建造日期:2008.12.08
//*******************************************************************
void TxLs164(unsigned char data)
{
unsigned char i;
i = 6; //送出六位
do
{
Dat = 0; //數(shù)據(jù)清零
Clk = 1; //時鐘置位
Clk = 0; //時鐘清零
}
while (--i); //循環(huán)發(fā)送
i = 6; //送出六位
do
{
Dat = 0; //先高后低
if (data & 0x20) Dat = 1;
Clk = 1; //時鐘置位
data <<= 1; //數(shù)據(jù)左移
Clk = 0; //時鐘清零
}
while (--i); //循環(huán)發(fā)送
}
//*******************************************************************
//函數(shù)名稱: WriteData(data, rs);
//輸入?yún)?shù):待寫數(shù)據(jù), 0 = 指令,1 = 數(shù)據(jù)
//輸出參數(shù):無
//功能描述:數(shù)據(jù)寫入LCD
//建造日期:2008.12.08
//*******************************************************************
void WriteData(unsigned char data, unsigned char rs)
{
unsigned char temp;
temp = data >> 4; //取高四位
temp |= 1 << 5; //使用置位
if (rs & 0x01) temp |= 1 << 4; //數(shù)據(jù)選擇
TxLs164(temp); //寫高四位
Dat = 1; //使能下沿
Dat = 0;
DelayUs(50); //延時等待
temp = data & 0x0f; //取低四位
temp |= 1 << 5; //使用置位
if (rs & 0x01) temp |= 1 << 4; //數(shù)據(jù)選擇
TxLs164(temp); //寫高四位
Dat = 1; //使能下沿
Dat = 0;
DelayUs(50); //延時等待
}
//*******************************************************************
//函數(shù)名稱:AddrSite(x, y);
//輸入?yún)?shù):坐標參數(shù)
//輸出參數(shù):無
//功能描述:設(shè)置顯示地址
//建造日期:2008.12.08
//*******************************************************************
void AddrSite(unsigned char x, unsigned char y)
{
x &= 0x3f; //截取地址
if (y == 0)
{
WriteData((0x80 | x), 0); //首行地址
}
else
{
WriteData((0xc0 | x), 0); //次行地址
}
}
//*******************************************************************
//函數(shù)名稱:PrintChar(*s);
//輸入?yún)?shù):緩沖區(qū)首址
//輸出參數(shù):無
//功能描述:字符串輸出顯示
//建造日期:2008.12.08
//*******************************************************************
void PrintChar(unsigned char *s)
{
while(*s)
{
WriteData(*s, 1); //字符數(shù)據(jù)
s++; //下個字符
}
}
//*******************************************************************
//函數(shù)名稱:LcdInit();
//輸入?yún)?shù):無
//輸出參數(shù):無
//功能描述:液晶初始化
//建造日期:2008.12.08
//*******************************************************************
void LcdInit(void)
{
unsigned char i = 3;
TxLs164(0x23); //接口設(shè)置
do
{
Dat = 1; //使能下沿
Dat = 0;
DelayUs(50); //延時等待
}
while (--i);
TxLs164(0x22); //四線模式
Dat = 1; //使能下沿
Dat = 0;
DelayUs(50); //延時等待
WriteData(0x28, 0); //接口設(shè)置
WriteData(0x0c, 0); //顯示打開
WriteData(0x01, 0); //顯示清屏
WriteData(0x06, 0); //光標右移
}
//*******************************************************************
//函數(shù)名稱:ShiftChar(*buff);
//輸入?yún)?shù):緩沖區(qū)首址, 0 = 左移 1 = 右移
//輸出參數(shù):無
//功能描述:移動字符
//建造日期:2008.12.08
//*******************************************************************
void ShiftChar(unsigned char *buff, unsigned char rl)
{
unsigned char temp, i;
if (rl & 0x01) //字符右移
{
temp = buff[15]; //取尾字符
for (i = 15; i > 0; i--)
{
buff[i] = buff[i - 1]; //數(shù)據(jù)右移
}
buff[0] = temp; //首尾交換
}
else //字符左移
{
temp = buff[0]; //取首字符
for (i = 0; i < 15; i++)
{
buff[i] = buff[i + 1]; //數(shù)據(jù)左移
}
buff[15] = temp; //字符交換
}
}
//*******************************************************************
//函數(shù)名稱:main();
//輸入?yún)?shù):無
//輸出參數(shù):無
//功能描述:主要程序
//建造日期:2008.12.08
//*******************************************************************
void main(void)
{
unsigned char i, rl;
PortInit(); //腳位設(shè)置
ConInit(); //配置設(shè)置
LcdInit(); //液晶設(shè)置
DelayMs(50); //短暫延時
AddrSite(0, 0); //坐標設(shè)置
PrintChar(TopChar); //發(fā)送字符
i = 0; //移動記數(shù)
rl = 0; //左右移動
while (1)
{
if (i++ > 200) //移動記數(shù)
{
i = 0; //記數(shù)清零
rl ^= 0x01; //移動取反
}
DelayMs(250); //延時顯示
ShiftChar(BotChar, rl); //移動字符
AddrSite(0, 1); //坐標設(shè)置
PrintChar(BotChar); //發(fā)送字符
}
}
源代碼下載:http://www.zg4o1577.cn/f/1602ym.rar
仿真文件下載:http://www.zg4o1577.cn/f/1602fz.rar