Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / C 和 汇编语言的混合编程(实时控制TLC1549的实现)

//主程序#include"LCD12864.h"//精度要根据你的基准电压/1024来计算出来!要注意
#define TLCPER 0.00421
uchar code Tlc_Table[]="0123456789";
uchar Tlc_Display[]="0.0000 V";extern uint Tlc1549(void);void GetDisplayVoltage()
{
 uchar a,b,c,d,e;
 uint tmp;   
 unsigned long value;
 tmp = Tlc1549();                                 //sampling
 value = tmp * (TLCPER * 10000) ;  //放大10000倍,48~50000
 
 a = (value / 10000) % 10;
 b = (value / 1000) % 10;
 c = (value / 100) % 10;
 d = (value / 10) % 10;
    e = value % 10;   
 
 Tlc_Display[0]=Tlc_Table[a];
 Tlc_Display[2]=Tlc_Table[b];
 Tlc_Display[3]=Tlc_Table[c];
 Tlc_Display[4]=Tlc_Table[d];
 Tlc_Display[5]=Tlc_Table[e];
}
void main()
{
 
 Delay400Ms();  //启动等待,等LCD讲入工作状态
    LCDInit();        //LCM初始化
 while(1){
 GetDisplayVoltage();
 DisplayListChar(0,1,Tlc_Display);
 }
}//汇编语言源程序NAME TLC1549TLC_SCL BIT P1.7 //TLC1549引脚定义
TLC_SDA BIT P1.6
TLC_CS  BIT P1.5?PR?Tlc1549?TLC1549  SEGMENT CODE
?DT?Tlc1549?TLC1549  SEGMENT DATA OVERLAYABLE
 PUBLIC Tlc1549 RSEG  ?DT?Tlc1549?TLC1549
?Tlc1549?BYTE:
       temp?040:   DS   2 RSEG  ?PR?Tlc1549?TLC1549
Tlc1549:
 USING 0
; {
  PUSH PSW
  MOV R5,#10              ;ten clock for ready work
  SETB TLC_CS
  CLR  TLC_SCL
  NOP
  NOP
READY:
  SETB TLC_SCL
  NOP
  NOP
  CLR  TLC_SCL
  DJNZ R5,READY
  CLR  TLC_CS
  NOP
  NOP
  SETB TLC_CS
  MOV  A,#0
  CLR  EA       ;stop break
  CLR  TLC_CS
  NOP
  NOP
  SETB TLC_SCL
  CLR  C       ;get first two bit
  MOV  C,TLC_SDA                    ;get first MSB
  RLC  A
  CLR  TLC_SCL
  NOP
  CLR  C
  SETB TLC_SCL
  MOV  C,TLC_SDA                  ;get secondary MSB
  RLC  A
  MOV  temp?040,A                  ;get two MSB
  CLR  TLC_SCL
  MOV  R5,#8                            ;get last eight bit
  MOV A,#0
LOWBIT:
        SETB TLC_SCL
  CLR C
  MOV C,TLC_SDA
  RLC A
  CLR TLC_SCL
  DJNZ R5,LOWBIT
  MOV temp?040+01H,A       ;gain last eight bit     MOV  R6,temp?040
        MOV  R7,temp?040+01H; }   ; SOURCE LINE # 7
?C0001:
      POP PSW
  SETB EA                               ;allow break
  RET  
; END OF Tlc1549 END//LCD12864.c#include"LCD12864.h"
//写数据
void WriteDataLCD(uchar WDLCD)
{
 ReadStatusLCD(); //检测忙
 LCD_RS = 1;
 LCD_RW = 0;
 LCD_Data = WDLCD;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 0;
}//写指令
void WriteCommandLCD(uchar WCLCD,BuysC) //BuysC为0时忽略忙检测
{
 if (BuysC) ReadStatusLCD(); //根据需要检测忙
 LCD_RS = 0;
 LCD_RW = 0;
 LCD_Data = WCLCD;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 1;
 LCD_E = 0; 
}//读数据
uchar ReadDataLCD(void)
{
 LCD_RS = 1;
 LCD_RW = 1;
 LCD_E = 0;
 LCD_E = 0;
 LCD_E = 1;
 return(LCD_Data);
}//读状态
uchar ReadStatusLCD(void)
{
 LCD_Data = 0xFF;
 LCD_RS = 0;
 LCD_RW = 1;
 LCD_E = 1;
 while (LCD_Data & Busy); //检测忙信号
 LCD_E = 0;
 return(LCD_Data);
}void LCDInit(void) //LCM初始化
{
 WriteCommandLCD(0x30,1); //显示模式设置,开始要求每次检测忙信号
 WriteCommandLCD(0x01,1); //显示清屏
 WriteCommandLCD(0x06,1); // 显示光标移动设置
 WriteCommandLCD(0x0C,1); // 显示开及光标设置
}
void LCDClear(void) //清屏
{
 WriteCommandLCD(0x01,1); //显示清屏
 WriteCommandLCD(0x34,1); // 显示光标移动设置
 WriteCommandLCD(0x30,1); // 显示开及光标设置
}
void LCDFlash(void) //闪烁效果
{
 WriteCommandLCD(0x08,1); //显示清屏
 Delay400Ms();
 WriteCommandLCD(0x0c,1); // 显示开及光标设置
 Delay400Ms();
 WriteCommandLCD(0x08,1); //显示清屏
 Delay400Ms();
 WriteCommandLCD(0x0c,1); // 显示开及光标设置
 Delay400Ms();
 WriteCommandLCD(0x08,1); //显示清屏
 Delay400Ms();
}
//按指定位置显示一个字符
void DisplayOneChar(uchar X, uchar Y, uchar DData)
{
 if(Y<1)
  Y=1;
 if(Y>4)
  Y=4;
 X &= 0x0F; //限制X不能大于16,Y不能大于1
 switch(Y){
 case 1:X|=0X80;break;
 case 2:X|=0X90;break;
 case 3:X|=0X88;break;
 case 4:X|=0X98;break;
 }
 WriteCommandLCD(X, 0); //这里不检测忙信号,发送地址码
 WriteDataLCD(DData);
}void DisplayListChar(uchar X, uchar Y, uchar  *DData)
{
 uchar ListLength,X2;
  ListLength = 0;
  X2=X;
 if(Y<1)
  Y=1;
 if(Y>4)
  Y=4;
 X &= 0x0F; //限制X不能大于16,Y在1-4之内
 switch(Y){
 case 1:X2|=0X80;break; //根据行数来选择相应地址
 case 2:X2|=0X90;break;
 case 3:X2|=0X88;break;
 case 4:X2|=0X98;break;
 }
 WriteCommandLCD(X2, 1); //发送地址码
  while (DData[ListLength]>=0x20) //若到达字串尾则退出
  {
   if (X <= 0x0F) //X坐标应小于0xF
    {
     WriteDataLCD(DData[ListLength]);
     ListLength++;
  X++;
  Delay5Ms();
    }
  }
}
//图形显示122*32
void DisplayImage (uchar code *DData){
 uchar x,y,i;
 unsigned int tmp=0;
 for(i=0;i<9;){  //分两屏,上半屏和下半屏,因为起始地址不同,需要分开
 for(x=0;x<32;x++){    //32行
  WriteCommandLCD(0x34,1);
  WriteCommandLCD((0x80+x),1);//列地址
  WriteCommandLCD((0x80+i),1); //行地址,下半屏,即第三行地址0X88
  WriteCommandLCD(0x30,1); 
  for(y=0;y<16;y++)
   WriteDataLCD(DData[tmp+y]);//读取数据写入LCD
  tmp+=16; 
 }
 i+=8;
 }
 WriteCommandLCD(0x36,1); //扩充功能设定
 WriteCommandLCD(0x30,1);
}//5ms延时
void Delay5Ms(void)
{
 unsigned int TempCyc = 5552;
 while(TempCyc--);
}//400ms延时
void Delay400Ms(void)
{
 uchar TempCycA = 5;
 unsigned int TempCycB;
 while(TempCycA--)
 {
  TempCycB=7269;
  while(TempCycB--);
 };
}
 //:CD12864.h
//============================================================
//Header include
#ifndef __LCD12864_H__
#define __LCD12864_H__#ifndef __HEADER_H__#define __HEADER_H__
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int#endif//============================================================
//函数声明extern void WriteDataLCD(uchar WDLCD);
extern void WriteCommandLCD(uchar WCLCD,BuysC);
extern uchar ReadDataLCD(void);
extern uchar ReadStatusLCD(void);
extern void LCDInit(void);
extern void LCDClear(void);
extern void LCDFlash(void);
extern void DisplayOneChar(uchar X, uchar Y, uchar DData);
//void DisplayListChar(uchar X, uchar Y, uchar code *DData);
extern void DisplayListChar(uchar X, uchar Y, uchar *DData);
extern void DisplayImage (uchar code *DData);
extern void Delay5Ms(void);
extern void Delay400Ms(void);
  
//============================================================
//此为硬件配置,请作相应的修改
sbit LCD_RS=P1^0;//定义引脚
sbit LCD_RW=P1^1;
sbit LCD_E=P1^2;
sbit PSB =P3^6;  //PSB脚为12864-12系列的串、并通讯功能切换,我们使用8位并行接口,PSB=1
#define LCD_Data P2
#define Busy    0x80 //用于检测LCD状态字中的Busy标识#endif