找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1149|回复: 6
收起左侧

单片机使用两组ISP同时进行通信出现干拢现象

[复制链接]
ID:322939 发表于 2022-3-10 21:14 | 显示全部楼层 |阅读模式
做个智能电表,MCU芯片使用STC15W408AS,计量芯片为CS5463,LCD显示,驱动用1621B,显示电压,电流,功率,功率因数,每组4位显示。现在是系统同时进行ISP通信,LCD会没有显示,如果取消计量芯片AD读取,LCD就正常显示,有时候计量芯片可以显示数值但会闪烁肉眼看见扫描时间不够屏幕模糊闪烁情况。难道计量芯片在读取运算时产生的时间延迟造成通信时序混乱吗?下面程序请各位大佬帮看下。多谢!

单片机源程序如下:
  1. #include "STC15.H"
  2. #include "intrins.h"
  3. #include <string.h>
  4. #define u8 unsigned char
  5. #define u16  unsigned int
  6. #define u32 unsigned long
  7.                
  8. #define BIAS 0x52//100 001010010X 4COM
  9. #define RCosc 0x30//100 000110000X ??RC???
  10. #define LCD_on 0x06//100 000000110X ??LCD?????
  11. #define LCD_off 0x04//100 000000100X ??LCD??
  12. #define SYS_en 0x02//100 000000010X 打开振荡器
  13. #define SYS_dis 0x00//关振荡器和偏压器
  14. #define WDT_dis 0X0a//关看门狗
  15. #define _Nop()        _nop_();_nop_();_nop_()

  16. #define CS5463_VScale       525             //计算电压比例,220V*250mv/110mv=500V
  17. #define CS5463_IScale       (250/10)        //计算电流比例

  18. #define READ_MASK                  0xBF            //读寄存器
  19. #define CMD_SYNC0            0XFE          //½áêø′®¿úÖØDÂ3õê¼»ˉ
  20. #define CMD_SYNC1            0XFF          //¿aê¼′®¿úÖØDÂ3õê¼»ˉ
  21. #define REG_CONFR           0x40           //ÅäÖÃ
  22. #define REG_CYCCONT         0x4A           //1个计算周期的AD转换
  23. #define REG_STATUSR         0x5E         //×′ì¬
  24. #define REG_MODER           0x64          //2ù×÷Ä£ê½
  25. #define REG_MASKR           0x74          //ÖD¶ÏÆá±Î
  26. #define REG_CTRLR           0x78          //¿ØÖÆ
  27. #define CMD_STARTC           0XE8          //执行连续计算周期

  28. #define REG_VRMSR           0X18          //VRMS
  29. #define REG_IRMSR           0X16          //IRMS
  30. #define REG_Pactive           0X14          //Pactive

  31. static u8 RX_Buff[4];                                        //CS5463读写缓冲区
  32. u8 sta;                                                                        //芯片状态
  33. void SendCmd_1621(u8 command);
  34. void t0_tem(void);
  35. void Write_1621(u8 addr, u8 sdata);
  36. void SendBit_1621(unsigned char datas,unsigned char cnt);        
  37. void uDelay(u8 j);
  38. void Delay(unsigned int Time);
  39. void Ht1621WrAllData(void);
  40. u16 num=0;        
  41. u8 k=0;        
  42.         
  43. sbit LCD_CS=P3^7;

  44. sbit LCD_WR=P3^3;
  45. sbit LCD_DATA=P3^2;

  46. sbit CS_RES=P1^1;
  47. sbit CS_SDI=P1^2;
  48. sbit CS_SCLK=P1^3;
  49. sbit CS_SDO=P1^4;
  50. sbit CS_CS=P1^5;

  51. sbit KEY=P3^0;

  52. u8 code num_data[]={0xf5,0x05,0xd3,0x97,0x27,0xb6,0xf6,0x15,0xf7,0xb7};//0-9字库

  53. /*****************IO初始化***************/
  54. void IO_init(void)
  55. {
  56.         P1M0=0xef;
  57.         P1M1=0x10;
  58.         P3M0=0xff;
  59.         P3M1=0x01;
  60.         P5M0=0x00;
  61.         P5M1=0xff;
  62. }
  63. /******************延时子函数******************/

  64. void uDelay(u8 j)
  65. {
  66.   u8 i;
  67.   for(;j>0;j--)
  68.         { for(i=0;i<255;i--)
  69.                 {
  70.                 ;
  71.                 }
  72.         }
  73. }
  74. void Delay(unsigned int Time)//50MS
  75. {
  76.          u8 i;
  77.          TMOD=0x01;
  78.          TH0=(65536-50000)/256;
  79.          TL0=(65536-50000)%256;
  80.          TR0=1;
  81.          for(i=0;i<Time;i++)
  82.          {
  83.                  while(~TF0);
  84.                  TF0=0;
  85.                  TH0=(65536-50000)/256;
  86.          TL0=(65536-50000)%256;
  87.          }
  88. }
  89. /******************5460命令函数*******************/
  90. static void CS5463CMD(u8 cmd)
  91. {
  92. u8 i;
  93. CS_SCLK=1;
  94. CS_CS=0;
  95. i = 0;
  96. while(i<8)
  97. {
  98.           uDelay(5);
  99.         CS_SCLK = 0;
  100.         if(cmd&0x80)
  101.                 CS_SDI=1;
  102.         else               
  103.                 CS_SDI=0;
  104.         uDelay(5);
  105.         CS_SCLK=1;                                         //时钟上升沿数据被写入
  106.         cmd<<=1;
  107.         i++;
  108. }
  109. uDelay(5);
  110. CS_CS=1;
  111. }
  112. /******************写寄存器函数******************/
  113. void CS5463WriteReg(u8 addr,u8 *p)
  114. {
  115. u8 i,j;
  116. u8 dat;
  117. CS_SCLK = 1;
  118. CS_CS = 0;
  119. i = 0;
  120. while(i<8)
  121. {
  122.           uDelay(5);
  123.         CS_SCLK = 0;
  124.         if(addr&0x80)
  125.                 CS_SDI=1;
  126.         else                 
  127.                 CS_SDI=0;
  128.         uDelay(5);
  129.         CS_SCLK = 1;                                         //在时钟上升沿数据被写入5463
  130.         addr<<= 1;
  131.         i++;
  132. }
  133. j = 0;
  134. while(j<3)
  135. {
  136.           dat = *(p+j);
  137.         i = 0;
  138.         while(i<8)
  139.         {
  140.                   uDelay(5);
  141.                   CS_SCLK = 0;
  142.                 if(dat&0x80)
  143.                         CS_SDI= 1;
  144.                 else               
  145.                         CS_SDI= 0;
  146.                 uDelay(5);
  147.                 CS_SCLK = 1;                                  //Ôúê±ÖóéÏéyÑØ£¬êy¾Y±»D′èëCS5463
  148.                 dat <<= 1;
  149.                 i++;
  150.         }
  151.         j++;
  152. }
  153. uDelay(5);
  154. CS_CS = 1;
  155. }
  156. /*******************读寄存器函数******************/
  157. void CS5463ReadReg(u8 addr,u8 *p)
  158. {
  159. u8 i,j;
  160. u8 dat;
  161. CS_SCLK = 0;
  162. CS_CS = 0;
  163. addr &= READ_MASK;
  164. i = 0;
  165. while(i<8)
  166. {
  167.           uDelay(5);
  168.         CS_SCLK = 0;
  169.         if(addr&0x80)
  170.                 CS_SDI = 1;
  171.         else                 
  172.                 CS_SDI = 0;
  173.         uDelay(5);
  174.         CS_SCLK = 1;
  175.         addr <<= 1;                                         //Ôúê±ÖóéÏéyÑØ£¬êy¾Y±»D′èëCS5463
  176.         i++;
  177. }
  178. uDelay(5);
  179. CS_SDI = 1;
  180. j = 0;
  181. while(j<3)
  182. {
  183.         i = 0;
  184.         dat = 0;
  185.         while(i<8)
  186.         {
  187.                 if(i==7)
  188.                         CS_SDI=0;
  189.                 else        
  190.                         CS_SDI=1;
  191.                 CS_SCLK = 0;
  192.                 uDelay(5);
  193.                 dat <<= 1;                                                
  194.                 if(CS_SDO)
  195.                         dat|= 0x01;
  196.                 else        
  197.                         dat &= 0xFE;
  198.                 CS_SCLK = 1;
  199.                 uDelay(5);                                                         
  200.                 i++;
  201.         }
  202.         *(p+j) = dat;
  203.         j++;
  204. }
  205. CS_SDI = 1;
  206. CS_CS = 1;
  207. }
  208. /******************复位和初始化函数*******************/
  209. u8 CS5463_Init(void)           
  210. {
  211. CS_RES = 0;
  212. uDelay(20);
  213. CS_RES= 1;
  214. uDelay(10);
  215. //----------------------
  216. //·¢Ëíí¬2½DòáD
  217. RX_Buff[0] = CMD_SYNC1;
  218. RX_Buff[1] = CMD_SYNC1;
  219. RX_Buff[2] = CMD_SYNC0;
  220. CS5463WriteReg(CMD_SYNC1,RX_Buff);               
  221. //----------------------

  222. RX_Buff[0] = 0x00;                                                
  223. RX_Buff[1] = 0x00;
  224. RX_Buff[2] = 0x01;
  225. CS5463WriteReg(REG_CONFR,RX_Buff);         
  226. //----------------------

  227. RX_Buff[0] = 0x00; //B0000_0000;                                                  
  228. RX_Buff[1] = 0x00;//B0000_0000;
  229. RX_Buff[2] = 0x60;//B0110_0000;
  230. CS5463WriteReg(REG_MODER,RX_Buff);          //#define REG_MODER           0x64         
  231. RX_Buff[0] = 0x00;
  232. RX_Buff[1] = 0x0F;
  233. RX_Buff[2] = 0xA0;                                                
  234. CS5463WriteReg(REG_CYCCONT,RX_Buff);        

  235. //----------------------
  236. RX_Buff[0] = 0xFF;
  237. RX_Buff[1] = 0xFF;
  238. RX_Buff[2] = 0xFF;
  239. CS5463WriteReg(REG_STATUSR,RX_Buff);        
  240. //----------------------
  241. RX_Buff[0] = 0x80;                                                
  242. RX_Buff[1] = 0x00;
  243. RX_Buff[2] = 0x80;                                                
  244. CS5463WriteReg(REG_MASKR,RX_Buff);               
  245. //----------------------
  246. RX_Buff[0] = 0x00;
  247. RX_Buff[1] = 0x00;
  248. RX_Buff[2] = 0x00;
  249. CS5463WriteReg(REG_CTRLR,RX_Buff);                //3õê¼»ˉ--¿ØÖƼÄ′æÆ÷   #define REG_CTRLR           0x78          //¿ØÖÆ  
  250. //----------------------
  251. CS5463CMD(CMD_STARTC);                                           //Æô¶ˉá¬Dø×a»»            #define CMD_STARTC           0XE8          //Ö′DDá¬Dø¼ÆËãÖüÆú
  252. //CS5463_Status = 0;                                                //3õê¼»ˉèÎÎñ½ø3ì×′ì¬
  253. //Load_Status = 0;
  254. //CS5463_CrmsSmallCunt = 0;
  255. //CS5463_CrmsOverCunt = 0;
  256. return(1);                    //Ö»òa×öíêÕaD©2½Öè¾í·μ»Øtrue  1
  257. }
  258. /**********************复位状态寄存器******************/
  259. static void CS5463_ResetStatusReg(void)
  260. {
  261. RX_Buff[0] = 0xFF;
  262. RX_Buff[1] = 0xFF;
  263. RX_Buff[2] = 0xFF;
  264. CS5463WriteReg(0x5E,RX_Buff);                //
  265. }
  266. /*******************读取状态寄存器*******************/
  267. static u8 CS5463_GetStatusReg(void)
  268. {
  269. u8 sta=0;
  270. CS5463ReadReg(0x1E,RX_Buff);           //1E êÇê2Ã′£¿   ×′쬼Ä′æÆ÷
  271. if(RX_Buff[0]&0x80)                                           //¼ì2a£oμçá÷¡¢μçÑ1¡¢1|Âê2aá¿êÇ·ñíê±Ï
  272. {

  273.         if((RX_Buff[0]&0x03)||(RX_Buff[1]&0x70))
  274.         {
  275.                  CS5463_ResetStatusReg();                //¸′λ×′쬼Ä′æÆ÷
  276.         }
  277.         else
  278.         {
  279.                 sta |= 0x01;//B0000_0001;        //Õaê2Ã′òa˼ »1¿éòÔÕaÑùD′Âe£¿ PT2017-2-8   ·Ö¸ô·ûÂe£¿
  280.         }
  281. }
  282. if(RX_Buff[2]&0x80)                                   //¼ì2a£oζè2aá¿êÇ·ñíê±Ï
  283. {
  284.           sta |=0x02; //B0000_0010;
  285. }
  286. return(sta);        
  287. }  
  288. /****************1621初始化函数********************/
  289. void HT1621_IO_init(void)
  290. {
  291.         LCD_WR=1;
  292.         LCD_DATA=1;
  293.         LCD_CS=1;
  294.    Delay(1);//50ms
  295.         SendCmd_1621(BIAS);//1/4COM
  296.         SendCmd_1621(RCosc);//内部振荡
  297.         SendCmd_1621(SYS_en);//打开振荡
  298.         SendCmd_1621(LCD_on);//开显示

  299. }
  300. /******************SendCmd(送命令)********************/
  301. void SendCmd_1621(u8 command)
  302. {
  303. LCD_CS=0;
  304. _Nop();
  305. SendBit_1621(0x80,4);
  306. SendBit_1621(command,8);

  307. LCD_CS=1;

  308. }        
  309. /****************Name:Write 1621(送数据和命令)*****************/
  310. void Write_1621(u8 addr, u8 sdata)
  311. {
  312.         LCD_CS=0;//打开片选
  313.         SendBit_1621(0xa0,3);//写入标志码《101》
  314.         SendBit_1621(addr<<2,6);//写入addr高6位(Y)
  315.         SendBit_1621(sdata,8);//写入sdata的8位(X)
  316.         _Nop();
  317.         LCD_CS=1;//关闭片选
  318. }
  319. /****************1621写字节函数************/
  320. void SendBit_1621(u8 datas,u8 cnt)//datas高位 cnt写入 ,高位在前
  321. {
  322.         u8 i;
  323.         for(i=0;i<cnt;i++)
  324.         {
  325.                 LCD_WR=0;

  326.                 if(datas&0x80)
  327.                         LCD_DATA=1;
  328.                 else
  329.                         LCD_DATA=0;
  330.         
  331.                   LCD_WR=1;

  332.                   datas<<=1;
  333.         }
  334. }
  335. /*********************电压显示*********************/
  336. static void CS5463_GetVoltRMS(void)
  337. {
  338.         u8 a0,a1,a2;
  339.         float G = 0.5,result;                //typedef float          fp32;          ¾íêǸ¡μãààDí
  340. u32 temp1;                          //  int
  341. u8 temp,i,j;                  //  byte
  342. CS5463ReadReg(REG_VRMSR,RX_Buff);
  343.         i = 0;
  344. result = 0;
  345. while(i<3)
  346. {
  347.           temp = RX_Buff[i];                                          
  348.         j = 0;
  349.         while(j<8)
  350.         {
  351.                  if(temp&0x80)
  352.                 {
  353.                          result += G;        
  354.                 }
  355.                 temp <<= 1;
  356.                 j++;
  357.                 G = G/2;        
  358.         }
  359.         i++;                                                               
  360. }                                                                                
  361. result=result*CS5463_VScale;
  362. result *= 100;                                                
  363. temp1=(u32)result;
  364.         a2=(temp1/100);
  365.         a1=(temp1/10)%10;
  366.         a0=temp1%10;
  367.         Write_1621(0,0x08);
  368.         Write_1621(2,num_data[a2]);
  369.         Write_1621(4,num_data[a1]);
  370.         Write_1621(6,num_data[a0]|0x08);
  371.         }
  372. /******************电流显示******************/
  373. static void CS5463_GetCurrentRMS(void)
  374. {
  375.         u8 T0,T1,T2,T3;
  376.         float G = 0.5,result;
  377. u32 temp1;
  378. u8 temp,i,j;
  379. CS5463ReadReg(REG_IRMSR,RX_Buff);
  380.          i = 0;
  381. result = 0;
  382. while(i<3)
  383. {
  384.           temp = RX_Buff[i];                                          
  385.         j = 0;
  386.         while(j<8)
  387.         {
  388.                  if(temp&0x80)
  389.                 {
  390.                          result += G;        
  391.                 }
  392.                 temp <<= 1;
  393.                 j++;
  394.                 G = G/2;        
  395.         }
  396.         i++;
  397. }
  398. result = result*CS5463_IScale;//I_Coff;                                       
  399. result *= 1000;                                                               
  400. temp1 = (u32)result;

  401.         T3=(temp1/1000);
  402.         T2=(temp1/100)%10;
  403.         T1=(temp1/10)%10;
  404.         T0=temp1%10;
  405.         Write_1621(8,num_data[T3]|0x08);
  406.         Write_1621(10,num_data[T2]|0x08);
  407.         Write_1621(12,num_data[T1]);
  408.         Write_1621(14,num_data[T0]|0x08);
  409.         }
  410. /*******************功率显示******************/
  411. static void CS5463_GetPactiveRMS(void)
  412. {
  413.          u8 U0,U1,U2,U3;
  414.         float G = 1.0,result;
  415. u8 temp,i,j;
  416. u32 temp1;
  417. CS5463ReadReg(0x14,RX_Buff);
  418.         temp = RX_Buff[0];
  419. if(temp&0x80)                                                         
  420. {
  421.           RX_Buff[0] = ~RX_Buff[0];                        
  422.         RX_Buff[1] = ~RX_Buff[1];
  423.         RX_Buff[2] = ~RX_Buff[2];                        
  424. }
  425. i = 0;
  426. result = 0;
  427. while(i<3)
  428. {
  429.           temp = RX_Buff[i];                                          
  430.         j = 0;
  431.         while(j<8)
  432.         {
  433.                  if(temp&0x80)
  434.                 {
  435.                          result += G;        
  436.                 }
  437.                 temp <<= 1;
  438.                 j++;
  439.                 G = G/2;        
  440.         }
  441.         i++;
  442. }
  443. result = result*13125;
  444. temp1 = (u32)result;
  445.         U3=(temp1/1000);
  446.         U2=(temp1/100)%10;
  447.         U1=(temp1/10)%10;
  448.         U0=temp1%10;
  449.         Write_1621(30,num_data[U3]);
  450.         Write_1621(28,num_data[U2]|0x08);
  451.         Write_1621(26,num_data[U1]|0x08);
  452.         Write_1621(24,num_data[U0]|0x08);
  453.         }

  454. /*******************功率因数********************/
  455. static void CS5463_GetPowerFactor(void)
  456. {
  457.         u8 E0,E1,E2,E3;
  458. //        u16 temp1=1234;
  459.         float G = 1.0,result;
  460. u8 temp,i,j;
  461. u32 temp1;
  462. CS5463ReadReg(0x32,RX_Buff);
  463.         temp = RX_Buff[0];
  464. if(temp&0x80)                                                          //èç1ûÎa¸oêy£¬¼ÆËãÔ-Âë
  465. {
  466.           RX_Buff[0] = ~RX_Buff[0];                        //±¾à′Îaè¡·′+1£¬ÕaàïòòÎa¾«¶èμÄÔ-òò£¬2»+1
  467.         RX_Buff[1] = ~RX_Buff[1];
  468.         RX_Buff[2] = ~RX_Buff[2];                        
  469. }
  470. i = 0;
  471. result = 0;
  472. while(i<3)
  473. {
  474.           temp = RX_Buff[i];                                          
  475.         j = 0;
  476.         while(j<8)
  477.         {
  478.                  if(temp&0x80)
  479.                 {
  480.                          result += G;        
  481.                 }
  482.                 temp <<= 1;
  483.                 j++;
  484.                 G = G/2;        
  485.         }
  486.         i++;
  487. }
  488. result *= 10000;
  489. temp1=(u32)result;
  490.         E3=(temp1/1000);
  491.         E2=(temp1/100)%10;
  492.         E1=(temp1/10)%10;
  493.         E0=temp1%10;
  494.         Write_1621(16,num_data[E0]|0x08);
  495.         Write_1621(18,num_data[E1]|0x08);
  496.         Write_1621(20,num_data[E2]|0x08);
  497.         Write_1621(22,num_data[E3]|0x08);
  498. }

  499. /***************清除1621显示*************/
  500. void HT1621_all_off(void)
  501. {
  502.         u8 t;
  503.         u8 Y=0;
  504.         for(t=0;t<32;t++)
  505.         {
  506.                 Write_1621(Y,0x00);
  507.                 Y++;
  508.         }
  509. }
  510. /****************全部点亮LCD***************/
  511.         void HT1621_all_on(void)
  512.         {
  513.                 u8  f;
  514.                 u8 G=0;
  515.                 for(f=0;f<32;f++)
  516.                 {
  517.                         Write_1621(G,0xff);
  518.                         G++;
  519.                 }
  520.         }
  521. /*****************主程序*******************/
  522. void main(void)
  523. {
  524.         
  525.         IO_init();
  526.         
  527.         HT1621_all_on();//全显示
  528.         HT1621_IO_init();//LCD初始化
  529.   Delay(20);
  530.   HT1621_all_off();//清屏

  531.         while(1)
  532.         {

  533.                 sta=CS5463_GetStatusReg();                          //检测中断
  534.                 if(0x01==(sta&0x01))                                           //获取电流电压
  535.                 {               
  536.                         
  537.                         CS5463_ResetStatusReg();                        //清除标志
  538.                         CS5463_GetVoltRMS();                                //电压
  539.                         CS5463_GetCurrentRMS();                                //电流
  540.                         CS5463_GetPactiveRMS();             //功率*/
  541.                         CS5463_GetPowerFactor();     //功率因数*/
  542.                 }
  543.         }        
  544. }
  545.         
复制代码
回复

使用道具 举报

ID:322939 发表于 2022-3-11 08:37 | 显示全部楼层
问题就是怎样处理多个SPI通信问题
回复

使用道具 举报

ID:322939 发表于 2022-3-11 10:13 | 显示全部楼层
那位大佬帮看看是那里出问题?
回复

使用道具 举报

ID:415064 发表于 2022-3-11 11:36 | 显示全部楼层
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;
         }
}
回复

使用道具 举报

ID:322939 发表于 2022-3-11 14:04 | 显示全部楼层
wojiaoguogai 发表于 2022-3-11 11:36
void uDelay(u8 j)
{
  u8 i;

楼上什么意思呢?如果使用软件延时,延时时间在毫秒以上放在主循环里,LCD也会不显示。反正在主循环里使用延时就会不显示。
回复

使用道具 举报

ID:844772 发表于 2022-3-11 16:03 | 显示全部楼层
感觉像是硬件问题,因为你的软件很简单,基本顺序执行,不应该影响显示,看一下通讯时的波形吧。另外,上边的延时后,记得关定时中断啊。
回复

使用道具 举报

ID:322939 发表于 2022-3-11 16:42 | 显示全部楼层

硬件没有那么复杂,没问题哦
lll.JPG
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表