找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 857|回复: 2
收起左侧

有试过用单片机定时器做SPI通信吗?

[复制链接]
ID:322939 发表于 2022-4-7 15:17 | 显示全部楼层 |阅读模式
我用软件写的SPI接口驱动1621显示,发现如果将delay延时几ms放在大循环内LCD显示会一闪一闪的现象,如取消延时则正常显示,不知是不是通信设置问题还是硬件问题?有大佬用定时器做SPI通信吗?请指点下,谢谢!

单片机源程序如下:
    #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_()
    08.#define BIAS 0x52//100 001010010X 4COM 09.#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_()

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




                                    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;
                                                 }
                                        }


                                        /******************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;
                                                }
                                        }
                                        /***************清除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)
                                        {
                                            u8 i=0;
                                                IO_init();

                                HT1621_IO_init();//LCD初始化






                                           HT1621_all_on();//全显示
                                          Delay(20);
                                          HT1621_all_off();//清屏
                                                while(1)
                                                {

       Write_1621(0,num_data[ i]);
              i++;
            Delay(10);//500ms
            if(i>9)
           {
              i=0;
                }
         }
}
回复

使用道具 举报

ID:752974 发表于 2022-4-8 09:01 | 显示全部楼层
spi接口可以用普通IO口线通过软件模拟,跟定时器无关,闪烁可能是刷新太慢的问题,或者只有现实的数据变化时再刷新LCD。试试看。
回复

使用道具 举报

ID:123289 发表于 2022-4-8 15:17 | 显示全部楼层
有嵌入式SPI的可以按说明要求去做。
没有嵌入式SPI的,如果自己写就很复杂了,估计楼主很难实现,可以提示下列几点:
一、制定好通讯协议
1、定义出CLK:即移位时间。
2、定义出:区分字节方法,即一个字节从何处开始,到何处结束。
3、定义出:帧开始的方式(同步头,或间隔一段时间),帧结束的方式(结束符或计算字节数量)。
二、发送
1、建立一个缓冲区,用于存放通讯数据。
2、用定时器中断实现CLK,每次中断从缓冲区中取出数据,并移动输出一位(注意是位,不是字节)。再依协议编写发送一个字节的程序、发送一帧的程序。
三、接收
1、建立一个缓冲区,用于存放通讯数据。
2、依协议规定,做出检出帧开始的方式(同步头),检出后起动CLK(可以起动定时器来实现),之后每次中断读入一位数据。
3、依协议规定,完成字节的拼装,拼将好一个字节后,依序存入接收缓冲区。
4、依协议规定,完成帧结束识别,结束本次通讯。
剩下的工作,就是分析、处理缓冲区中的数据了。
以上只是粗叙述,就已较复杂了。
不管如何,建议楼主,先弄清楚SPI的通讯原理,细至移位拼装过程。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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