c 控制 汇编语言,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 TLC1549

TLC_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

#include

#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标识

#endif0b1331709591d260c1c78e86d0c51c18.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值