做個智能電表,MCU芯片使用STC15W408AS,計量芯片為CS5463,LCD顯示,驅動用1621B,顯示電壓,電流,功率,功率因數,每組4位顯示。現在是系統同時進行ISP通信,LCD會沒有顯示,如果取消計量芯片AD讀取,LCD就正常顯示,有時候計量芯片可以顯示數值但會閃爍肉眼看見掃描時間不夠屏幕模糊閃爍情況。難道計量芯片在讀取運算時產生的時間延遲造成通信時序混亂嗎?下面程序請各位大佬幫看下。多謝!
單片機源程序如下:
- #include "STC15.H"
- #include "intrins.h"
- #include <string.h>
- #define u8 unsigned char
- #define u16 unsigned int
- #define u32 unsigned long
-
- #define BIAS 0x52//100 001010010X 4COM
- #define RCosc 0x30//100 000110000X ??RC???
- #define LCD_on 0x06//100 000000110X ??LCD?????
- #define LCD_off 0x04//100 000000100X ??LCD??
- #define SYS_en 0x02//100 000000010X 打開振蕩器
- #define SYS_dis 0x00//關振蕩器和偏壓器
- #define WDT_dis 0X0a//關看門狗
- #define _Nop() _nop_();_nop_();_nop_()
- #define CS5463_VScale 525 //計算電壓比例,220V*250mv/110mv=500V
- #define CS5463_IScale (250/10) //計算電流比例
- #define READ_MASK 0xBF //讀寄存器
- #define CMD_SYNC0 0XFE //½áêø′®¿úÖØDÂ3õê¼»ˉ
- #define CMD_SYNC1 0XFF //¿aê¼′®¿úÖØDÂ3õê¼»ˉ
- #define REG_CONFR 0x40 //ÅäÖÃ
- #define REG_CYCCONT 0x4A //1個計算周期的AD轉換
- #define REG_STATUSR 0x5E //×′ì¬
- #define REG_MODER 0x64 //2ù×÷Ä£ê½
- #define REG_MASKR 0x74 //ÖD¶ÏÆá±Î
- #define REG_CTRLR 0x78 //¿ØÖÆ
- #define CMD_STARTC 0XE8 //執行連續計算周期
- #define REG_VRMSR 0X18 //VRMS
- #define REG_IRMSR 0X16 //IRMS
- #define REG_Pactive 0X14 //Pactive
- static u8 RX_Buff[4]; //CS5463讀寫緩沖區
- u8 sta; //芯片狀態
- void SendCmd_1621(u8 command);
- void t0_tem(void);
- void Write_1621(u8 addr, u8 sdata);
- void SendBit_1621(unsigned char datas,unsigned char cnt);
- void uDelay(u8 j);
- void Delay(unsigned int Time);
- void Ht1621WrAllData(void);
- u16 num=0;
- u8 k=0;
-
- sbit LCD_CS=P3^7;
- sbit LCD_WR=P3^3;
- sbit LCD_DATA=P3^2;
- sbit CS_RES=P1^1;
- sbit CS_SDI=P1^2;
- sbit CS_SCLK=P1^3;
- sbit CS_SDO=P1^4;
- sbit CS_CS=P1^5;
- sbit KEY=P3^0;
- u8 code num_data[]={0xf5,0x05,0xd3,0x97,0x27,0xb6,0xf6,0x15,0xf7,0xb7};//0-9字庫
- /*****************IO初始化***************/
- void IO_init(void)
- {
- P1M0=0xef;
- P1M1=0x10;
- P3M0=0xff;
- P3M1=0x01;
- P5M0=0x00;
- P5M1=0xff;
- }
- /******************延時子函數******************/
- void uDelay(u8 j)
- {
- u8 i;
- for(;j>0;j--)
- { for(i=0;i<255;i--)
- {
- ;
- }
- }
- }
- void Delay(unsigned int Time)//50MS
- {
- u8 i;
- TMOD=0x01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- TR0=1;
- for(i=0;i<Time;i++)
- {
- while(~TF0);
- TF0=0;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- }
- }
- /******************5460命令函數*******************/
- static void CS5463CMD(u8 cmd)
- {
- u8 i;
- CS_SCLK=1;
- CS_CS=0;
- i = 0;
- while(i<8)
- {
- uDelay(5);
- CS_SCLK = 0;
- if(cmd&0x80)
- CS_SDI=1;
- else
- CS_SDI=0;
- uDelay(5);
- CS_SCLK=1; //時鐘上升沿數據被寫入
- cmd<<=1;
- i++;
- }
- uDelay(5);
- CS_CS=1;
- }
- /******************寫寄存器函數******************/
- void CS5463WriteReg(u8 addr,u8 *p)
- {
- u8 i,j;
- u8 dat;
- CS_SCLK = 1;
- CS_CS = 0;
- i = 0;
- while(i<8)
- {
- uDelay(5);
- CS_SCLK = 0;
- if(addr&0x80)
- CS_SDI=1;
- else
- CS_SDI=0;
- uDelay(5);
- CS_SCLK = 1; //在時鐘上升沿數據被寫入5463
- addr<<= 1;
- i++;
- }
- j = 0;
- while(j<3)
- {
- dat = *(p+j);
- i = 0;
- while(i<8)
- {
- uDelay(5);
- CS_SCLK = 0;
- if(dat&0x80)
- CS_SDI= 1;
- else
- CS_SDI= 0;
- uDelay(5);
- CS_SCLK = 1; //Ôúê±ÖóéÏéyÑØ£¬êy¾Y±»D′èëCS5463
- dat <<= 1;
- i++;
- }
- j++;
- }
- uDelay(5);
- CS_CS = 1;
- }
- /*******************讀寄存器函數******************/
- void CS5463ReadReg(u8 addr,u8 *p)
- {
- u8 i,j;
- u8 dat;
- CS_SCLK = 0;
- CS_CS = 0;
- addr &= READ_MASK;
- i = 0;
- while(i<8)
- {
- uDelay(5);
- CS_SCLK = 0;
- if(addr&0x80)
- CS_SDI = 1;
- else
- CS_SDI = 0;
- uDelay(5);
- CS_SCLK = 1;
- addr <<= 1; //Ôúê±ÖóéÏéyÑØ£¬êy¾Y±»D′èëCS5463
- i++;
- }
- uDelay(5);
- CS_SDI = 1;
- j = 0;
- while(j<3)
- {
- i = 0;
- dat = 0;
- while(i<8)
- {
- if(i==7)
- CS_SDI=0;
- else
- CS_SDI=1;
- CS_SCLK = 0;
- uDelay(5);
- dat <<= 1;
- if(CS_SDO)
- dat|= 0x01;
- else
- dat &= 0xFE;
- CS_SCLK = 1;
- uDelay(5);
- i++;
- }
- *(p+j) = dat;
- j++;
- }
- CS_SDI = 1;
- CS_CS = 1;
- }
- /******************復位和初始化函數*******************/
- u8 CS5463_Init(void)
- {
- CS_RES = 0;
- uDelay(20);
- CS_RES= 1;
- uDelay(10);
- //----------------------
- //·¢Ëíí¬2½DòáD
- RX_Buff[0] = CMD_SYNC1;
- RX_Buff[1] = CMD_SYNC1;
- RX_Buff[2] = CMD_SYNC0;
- CS5463WriteReg(CMD_SYNC1,RX_Buff);
- //----------------------
- RX_Buff[0] = 0x00;
- RX_Buff[1] = 0x00;
- RX_Buff[2] = 0x01;
- CS5463WriteReg(REG_CONFR,RX_Buff);
- //----------------------
- RX_Buff[0] = 0x00; //B0000_0000;
- RX_Buff[1] = 0x00;//B0000_0000;
- RX_Buff[2] = 0x60;//B0110_0000;
- CS5463WriteReg(REG_MODER,RX_Buff); //#define REG_MODER 0x64
- RX_Buff[0] = 0x00;
- RX_Buff[1] = 0x0F;
- RX_Buff[2] = 0xA0;
- CS5463WriteReg(REG_CYCCONT,RX_Buff);
- //----------------------
- RX_Buff[0] = 0xFF;
- RX_Buff[1] = 0xFF;
- RX_Buff[2] = 0xFF;
- CS5463WriteReg(REG_STATUSR,RX_Buff);
- //----------------------
- RX_Buff[0] = 0x80;
- RX_Buff[1] = 0x00;
- RX_Buff[2] = 0x80;
- CS5463WriteReg(REG_MASKR,RX_Buff);
- //----------------------
- RX_Buff[0] = 0x00;
- RX_Buff[1] = 0x00;
- RX_Buff[2] = 0x00;
- CS5463WriteReg(REG_CTRLR,RX_Buff); //3õê¼»ˉ--¿ØÖƼÄ′æÆ÷ #define REG_CTRLR 0x78 //¿ØÖÆ
- //----------------------
- CS5463CMD(CMD_STARTC); //Æô¶ˉá¬Dø×a»» #define CMD_STARTC 0XE8 //Ö′DDá¬Dø¼ÆËãÖüÆú
- //CS5463_Status = 0; //3õê¼»ˉèÎÎñ½ø3ì×′ì¬
- //Load_Status = 0;
- //CS5463_CrmsSmallCunt = 0;
- //CS5463_CrmsOverCunt = 0;
- return(1); //Ö»òa×öíêÕaD©2½Öè¾í·μ»Øtrue 1
- }
- /**********************復位狀態寄存器******************/
- static void CS5463_ResetStatusReg(void)
- {
- RX_Buff[0] = 0xFF;
- RX_Buff[1] = 0xFF;
- RX_Buff[2] = 0xFF;
- CS5463WriteReg(0x5E,RX_Buff); //
- }
- /*******************讀取狀態寄存器*******************/
- static u8 CS5463_GetStatusReg(void)
- {
- u8 sta=0;
- CS5463ReadReg(0x1E,RX_Buff); //1E êÇê2Ã′£¿ ×′쬼Ä′æÆ÷
- if(RX_Buff[0]&0x80) //¼ì2a£oμçá÷¡¢μçÑ1¡¢1|Âê2aá¿êÇ·ñíê±Ï
- {
- if((RX_Buff[0]&0x03)||(RX_Buff[1]&0x70))
- {
- CS5463_ResetStatusReg(); //¸′λ×′쬼Ä′æÆ÷
- }
- else
- {
- sta |= 0x01;//B0000_0001; //Õaê2Ã′òa˼ »1¿éòÔÕaÑùD′Âe£¿ PT2017-2-8 ·Ö¸ô·ûÂe£¿
- }
- }
- if(RX_Buff[2]&0x80) //¼ì2a£oζè2aá¿êÇ·ñíê±Ï
- {
- sta |=0x02; //B0000_0010;
- }
- return(sta);
- }
- /****************1621初始化函數********************/
- void HT1621_IO_init(void)
- {
- LCD_WR=1;
- LCD_DATA=1;
- LCD_CS=1;
- Delay(1);//50ms
- SendCmd_1621(BIAS);//1/4COM
- SendCmd_1621(RCosc);//內部振蕩
- SendCmd_1621(SYS_en);//打開振蕩
- SendCmd_1621(LCD_on);//開顯示
- }
- /******************SendCmd(送命令)********************/
- void SendCmd_1621(u8 command)
- {
- LCD_CS=0;
- _Nop();
- SendBit_1621(0x80,4);
- SendBit_1621(command,8);
- LCD_CS=1;
- }
- /****************Name:Write 1621(送數據和命令)*****************/
- void Write_1621(u8 addr, u8 sdata)
- {
- LCD_CS=0;//打開片選
- SendBit_1621(0xa0,3);//寫入標志碼《101》
- SendBit_1621(addr<<2,6);//寫入addr高6位(Y)
- SendBit_1621(sdata,8);//寫入sdata的8位(X)
- _Nop();
- LCD_CS=1;//關閉片選
- }
- /****************1621寫字節函數************/
- void SendBit_1621(u8 datas,u8 cnt)//datas高位 cnt寫入 ,高位在前
- {
- u8 i;
- for(i=0;i<cnt;i++)
- {
- LCD_WR=0;
- if(datas&0x80)
- LCD_DATA=1;
- else
- LCD_DATA=0;
-
- LCD_WR=1;
- datas<<=1;
- }
- }
- /*********************電壓顯示*********************/
- static void CS5463_GetVoltRMS(void)
- {
- u8 a0,a1,a2;
- float G = 0.5,result; //typedef float fp32; ¾íêǸ¡μãààDí
- u32 temp1; // int
- u8 temp,i,j; // byte
- CS5463ReadReg(REG_VRMSR,RX_Buff);
- i = 0;
- result = 0;
- while(i<3)
- {
- temp = RX_Buff[i];
- j = 0;
- while(j<8)
- {
- if(temp&0x80)
- {
- result += G;
- }
- temp <<= 1;
- j++;
- G = G/2;
- }
- i++;
- }
- result=result*CS5463_VScale;
- result *= 100;
- temp1=(u32)result;
- a2=(temp1/100);
- a1=(temp1/10)%10;
- a0=temp1%10;
- Write_1621(0,0x08);
- Write_1621(2,num_data[a2]);
- Write_1621(4,num_data[a1]);
- Write_1621(6,num_data[a0]|0x08);
- }
- /******************電流顯示******************/
- static void CS5463_GetCurrentRMS(void)
- {
- u8 T0,T1,T2,T3;
- float G = 0.5,result;
- u32 temp1;
- u8 temp,i,j;
- CS5463ReadReg(REG_IRMSR,RX_Buff);
- i = 0;
- result = 0;
- while(i<3)
- {
- temp = RX_Buff[i];
- j = 0;
- while(j<8)
- {
- if(temp&0x80)
- {
- result += G;
- }
- temp <<= 1;
- j++;
- G = G/2;
- }
- i++;
- }
- result = result*CS5463_IScale;//I_Coff;
- result *= 1000;
- temp1 = (u32)result;
- T3=(temp1/1000);
- T2=(temp1/100)%10;
- T1=(temp1/10)%10;
- T0=temp1%10;
- Write_1621(8,num_data[T3]|0x08);
- Write_1621(10,num_data[T2]|0x08);
- Write_1621(12,num_data[T1]);
- Write_1621(14,num_data[T0]|0x08);
- }
- /*******************功率顯示******************/
- static void CS5463_GetPactiveRMS(void)
- {
- u8 U0,U1,U2,U3;
- float G = 1.0,result;
- u8 temp,i,j;
- u32 temp1;
- CS5463ReadReg(0x14,RX_Buff);
- temp = RX_Buff[0];
- if(temp&0x80)
- {
- RX_Buff[0] = ~RX_Buff[0];
- RX_Buff[1] = ~RX_Buff[1];
- RX_Buff[2] = ~RX_Buff[2];
- }
- i = 0;
- result = 0;
- while(i<3)
- {
- temp = RX_Buff[i];
- j = 0;
- while(j<8)
- {
- if(temp&0x80)
- {
- result += G;
- }
- temp <<= 1;
- j++;
- G = G/2;
- }
- i++;
- }
- result = result*13125;
- temp1 = (u32)result;
- U3=(temp1/1000);
- U2=(temp1/100)%10;
- U1=(temp1/10)%10;
- U0=temp1%10;
- Write_1621(30,num_data[U3]);
- Write_1621(28,num_data[U2]|0x08);
- Write_1621(26,num_data[U1]|0x08);
- Write_1621(24,num_data[U0]|0x08);
- }
- /*******************功率因數********************/
- static void CS5463_GetPowerFactor(void)
- {
- u8 E0,E1,E2,E3;
- // u16 temp1=1234;
- float G = 1.0,result;
- u8 temp,i,j;
- u32 temp1;
- CS5463ReadReg(0x32,RX_Buff);
- temp = RX_Buff[0];
- if(temp&0x80) //èç1ûÎa¸oêy£¬¼ÆËãÔ-Âë
- {
- RX_Buff[0] = ~RX_Buff[0]; //±¾à′Îaè¡·′+1£¬ÕaàïòòÎa¾«¶èμÄÔ-òò£¬2»+1
- RX_Buff[1] = ~RX_Buff[1];
- RX_Buff[2] = ~RX_Buff[2];
- }
- i = 0;
- result = 0;
- while(i<3)
- {
- temp = RX_Buff[i];
- j = 0;
- while(j<8)
- {
- if(temp&0x80)
- {
- result += G;
- }
- temp <<= 1;
- j++;
- G = G/2;
- }
- i++;
- }
- result *= 10000;
- temp1=(u32)result;
- E3=(temp1/1000);
- E2=(temp1/100)%10;
- E1=(temp1/10)%10;
- E0=temp1%10;
- Write_1621(16,num_data[E0]|0x08);
- Write_1621(18,num_data[E1]|0x08);
- Write_1621(20,num_data[E2]|0x08);
- Write_1621(22,num_data[E3]|0x08);
- }
- /***************清除1621顯示*************/
- void HT1621_all_off(void)
- {
- u8 t;
- u8 Y=0;
- for(t=0;t<32;t++)
- {
- Write_1621(Y,0x00);
- Y++;
- }
- }
- /****************全部點亮LCD***************/
- void HT1621_all_on(void)
- {
- u8 f;
- u8 G=0;
- for(f=0;f<32;f++)
- {
- Write_1621(G,0xff);
- G++;
- }
- }
- /*****************主程序*******************/
- void main(void)
- {
-
- IO_init();
-
- HT1621_all_on();//全顯示
- HT1621_IO_init();//LCD初始化
- Delay(20);
- HT1621_all_off();//清屏
- while(1)
- {
- sta=CS5463_GetStatusReg(); //檢測中斷
- if(0x01==(sta&0x01)) //獲取電流電壓
- {
-
- CS5463_ResetStatusReg(); //清除標志
- CS5463_GetVoltRMS(); //電壓
- CS5463_GetCurrentRMS(); //電流
- CS5463_GetPactiveRMS(); //功率*/
- CS5463_GetPowerFactor(); //功率因數*/
- }
- }
- }
-
復制代碼 |