我现在由于系统用了SJA1000所以对系统采用了外部总线扩展的方式,电路图如下,大家帮忙看看我的地址译码锁存有错误吗?我的AD挂在系统上不管怎样读回来的值都是0我用的是MAX197,而液晶不管怎么样后不显示。郁闷呀。。。
伤不起呀。
求高手帮忙,
把我的代码附在下面望批评。
LCD代码
#include <reg52.h>
#include <absacc.h>
#include <stdio.h> //调试的时候添加
#define
LcdWriteCmdPort
XBYTE[0XA000]
//1602命令寫端口
#define
LcdWriteDataPort
XBYTE[0XA002]
//1602寫數據端口
#define
LcdStatusPort
XBYTE[0XA001]
//1602讀狀態端口
#define LCDCHECK (bit)1
//讀寫lcd模塊是是否檢測液晶模塊的狀態標誌宏
#define
LCDNOCHECK (bit)0
#define
LCDROW1 (unsigned char)0
//LCD模塊的行的宏定義
#define LCDROW2 (unsigned char)1
struct _LcdPoint{
// LCD 模塊的點的結構
unsigned char x;
unsigned char y;
};
typedef struct _LcdPoint LcdPosition;
//定義液晶模塊顯示位子的類型 用於存放當前液晶模塊的光標位子
LcdPosition LcdNowPosition;
/*=======================================================
寫控制字符子程序: E="1" RS="0" RW="0"
void LCDWriteCmd(unsigned char cmd,bit chekbusy_f)
參數一 :cmd.......需要寫入LCD模塊的命令字
參數二:chekbusy_f....是否需要檢測lcd模塊忙的標誌位
值為 LCDCHECK(需要檢測)
LCDNOCHECK(不需要檢測) 這兩個宏 已定義
=======================================================*/
void LCDWriteCmd(unsigned char cmd,bit chekbusy_f)
{
if(chekbusy_f)
while(LcdStatusPort&0x80)
//讀LCD狀態 讀出的最高位為1表示lcd忙 程序等待
{
printf("in check");
}
LcdWriteCmdPort=cmd;
}
/*=======================================================
寫字符數據子程序: E ="1" RS="1" RW="0"
void LCDWriteData(unsigned char wdata)
參數 wdata.....為需要寫入的數據
=======================================================*/
void LCDWriteData(unsigned char wdata)
{
//修改 不检测忙
while(LcdStatusPort&0x80);
//每次讀寫都需要檢測LCD是否忙
LcdWriteDataPort=wdata;
}
/*=====================================================
清除显示的数据 (清屏)
======================================================*/
void LCDClear()
{
LCDWriteCmd(0x01,LCDCHECK);
}
/*========================================================
延时函数
非精确延时
ms=1時定時為1.12ms
當ms增加時延時時間不是按倍數增加的
應該給其一定不補償量
=========================================================*/
void delay(unsigned char ms)
{
unsigned char i,j;
for(i=0;i<ms;i++)
for(j=0;j<255;j++);
}
/*======================================================
初始化lcd子程序
void LCDInitial()
將液晶初始話為 2行16個字符 無光標 模式
=======================================================*/
void LCDInitial()
{
delay(13);
LCDWriteCmd(0x38,LCDNOCHECK);
delay(3);
LCDWriteCmd(0x38,LCDNOCHECK);
//修改 不检测忙
delay(3);
LCDWriteCmd(0x38,LCDNOCHECK);
LCDWriteCmd(0x38,LCDCHECK);
//顯示模式設置
LCDWriteCmd(0x08,LCDCHECK);
//顯示關閉
LCDWriteCmd(0x06,LCDCHECK);
//顯示光標移動設置
LCDWriteCmd(0x0C,LCDCHECK);
//顯示打開 顯示光標設置
LCDClear();
//顯示清屏
LcdNowPosition.x=0;
//初始化LCD模塊的位置記錄
LcdNowPosition.y=0;
//printf("in init");
}
/*=======================================================
顯示位置定位設置
將光標位置設置到x,y坐標位子
void LCDSetLocation(unsigned char x,unsigned char y)
參數為需要在lcd模塊上顯示的位置坐標
坐標定義是lcd模塊的左上角為原點向右為x向下為y
x取值為0~15
y取值為0~1
定義了宏 LCDROW1 0
第一行
LCDROW2 1
第二行
=======================================================*/
void LCDSetLocation(unsigned char x,unsigned char y)
{
unsigned char temp;
x&=0x0f;
//確保坐標在顯示模塊的範圍內
y&=0x01;
LcdNowPosition.x=x;
//更行位置信息
LcdNowPosition.y=y;
if(y==1)
temp=x|0x40;
LCDWriteCmd(temp|0x80,LCDCHECK);
//設置地址指針的指令碼是0x80+地址碼(0~27h 40~67h)
}
/*=======================================================
在指定位置显示数出一个字符
void LCDShowChar(unsigned char x,unsigned char y,unsigned char showdata)
x,y:為需要顯示的字符的需要顯示的坐標
x值為0~15
y值為0~1或LCDROW1 LCDROW2
showdata 是需要顯示的字符
=======================================================*/
void LCDShowChar(unsigned char x,unsigned char y,unsigned char showdata)
{
LCDSetLocation(x,y);
LCDWriteData(showdata);
}
/*==========================================================
在指定位置處開始顯示一個字符串
void LCDShowString(unsigned char x,unsigned char y,unsigned char *buf)
x,y為位置坐標
buf為字符串指針
此函數具有自動換行的功能
===========================================================*/
void LCDShowString(unsigned char x,unsigned char y,unsigned char *buf)
{
unsigned char i=0,j=0;
unsigned char m_x,m_y;
unsigned char *p;
p=buf;
m_x=x;m_y=y;
while(*p!='\0')
//統計字符串的長度
{
i++;
p++;
}
for(j=0;j<i;j++)
{
LCDShowChar(m_x++,m_y,*(p+j));
if(m_x>15)
{
m_y^=1;
//換行,異或1,第一行則換到第零行,第零行則換到第一行
m_x=0;
}
}
//printf("in show");
}
max197代码
#include <reg52.h>
#include "max197.h"
#include <intrins.h>
#include <absacc.h>
#define nop _nop_()
/*====================================================
啟動max197轉換的子函數
該函數默認把max197設置到正常模式內部時鐘內部控制
轉換0~+5V範圍的模式
參數chanel代表選擇的通道號;有宏MAX197CH0~MAX197CH7
=======================================================*/
void MA197StartConvert(unsigned char chanel)
{
MAX197CS=0x40|chanel;
}
/*====================================================
max197中斷函數
在畢業設計所用的板子上MAX197使用了外部中斷1
讀取AD轉換結束後的數據到result中
=====================================================*/
void MA197_IRQ() interrupt 2 using 2
{
EX1=0; //關閉外部中斷1
result.MAX197Result.lsb=MAX197LSB; //讀取低八位的數據
nop;
nop;
result.MAX197Result.msb=MAX197MSB&0X0F;
//讀取高四位的數據
g_bADFlag=1; //通知系統AD轉換結束
EX1=1;
}
/*=====================================================
AD转换函数
调用该函数 返回AD转换的值 返回类型(unsigned int)
传入参数 表示需要的到那个通道的值
======================================================*/
unsigned int GetADResult(unsigned char ch)
{
unsigned int m_UintArray[SAMPDEEP];
//用来存储N次采样的结果
unsigned char i,j;
for(i=0;i<SAMPDEEP;i++)
{
MA197StartConvert(ch); //启动转换
while(g_bADFlag==0)
{;}
//等待AD转换完成
g_bADFlag=0;
//一次转换完成而下依次转换还没开始 所以为0
m_UintArray[i]=result.MAX197IntResult; //取回转换结果
}
for(i=0;i<SAMPDEEP-1;i++)
//排序
{
for(j=0;j<SAMPDEEP-1-i;j++)
{
if(m_UintArray[j]<m_UintArray[j+1])
{
m_UintArray[j+1]=m_UintArray[j]+m_UintArray[j+1];
m_UintArray[j]=m_UintArray[j+1]-m_UintArray[j];
m_UintArray[j+1]=m_UintArray[j+1]-m_UintArray[j];
}
}
}
return (m_UintArray[SAMPDEEP/2]);
} |