歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C 和 匯編語言的混合編程(實時控制TLC1549的實現)

C 和 匯編語言的混合編程(實時控制TLC1549的實現)

日期:2017/3/1 10:37:35   编辑:Linux編程

//主程序

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

Copyright © Linux教程網 All Rights Reserved