找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2844|回复: 0
收起左侧

PIC16F877A单片机采用IO模拟SPI进行主从机通信仿真代码

[复制链接]
ID:883568 发表于 2021-4-10 17:01 | 显示全部楼层 |阅读模式
简介,
主机采用IO口进行模拟SPI信号对从机进行数据通信。
PROTEUS原理图,
0.png
仿真结果与波形,波形等,由于篇幅问题无法体现。
总结,
源程序与PROTEUS文件都上传了,欢迎下载。

从机单片机源程序如下:
  1. /*
  2. * File:   SLAVE-IO.c
  3. * Author: jiejiechen
  4. *
  5. * Created on 2021年4月9日, 上午10:54
  6. */
  7. #pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
  8. #pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
  9. #pragma config PWRTE = ON       // Power-up Timer Enable bit (PWRT enabled)
  10. #pragma config BOREN = ON       // Brown-out Reset Enable bit (BOR enabled)
  11. #pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
  12. #pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
  13. #pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
  14. #pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
  15. #include <xc.h>
  16. #define uint unsigned int
  17. #define uchar unsigned char
  18. #define SCK RC3        //SPI时钟端
  19. #define SDI RC4
  20. #define SDO RC5        //SPI数据输出端
  21. uint ERROR=0,flag=0x17;
  22. void init();
  23. void delayms(uint x);
  24. communication(uint data);
  25. communication_IO(uchar A);
  26. void main(void) {
  27.     uint temp1=0,temp2=0;
  28.      delayms(500);
  29.     init();
  30.     ERROR=0;
  31.     temp1=communication(0);//以写“0”代读,接收来至主机的数据。temp1=0xcc
  32.     RB0=1;
  33.     temp2=communication(0xe5);
  34.     if(temp1!=0)//判断是否接收到数据
  35.         RB1=1;
  36.     if(temp1!=flag)
  37.         ERROR=1;
  38.     if(ERROR==1)
  39.         RB2=0;
  40.     else
  41.         RB2=1;
  42.     PORTD=temp1;
  43.     //PORTD=temp1;
  44.     //RB2=1;
  45.     while(1);
  46.     return;
  47. }
  48. void init()
  49. {
  50.     SSPSTAT=0X00;
  51.     SSPCON=0X34;
  52.     TRISC=0B00011000;
  53.     TRISD=0X00;
  54.     PORTD=0X00;
  55.     ADCON1=0B00000110;
  56.     TRISA5=1;
  57.     TRISB=0X00;
  58.     PORTB=0X00;
  59. }
  60. void delayms(uint x)
  61. {
  62.     uchar a=0,b=0;
  63.     for(a=x;a>0;a--)
  64.         for(b=110;b>0;b--)
  65.             ;
  66. }
  67. communication(uint data)
  68. {
  69.     uint BUF=0;
  70.     SSPBUF=data;
  71.     while(BF==0);
  72.     BUF=SSPBUF;//在讲从机只设置为接收器时,主机发完数据后,不去读数据也是可以的。
  73.     return(BUF);
  74. }
  75. /*
  76. communication_IO(uchar A)
  77. {
  78.     SCK=1;
  79.     uint BUF=0;
  80.     uchar temp=0,i=0;
  81.     temp=A;
  82.     for(i=0;i<8;i++)         //移动一个字节中的八位。
  83.     {
  84.         SCK=0;
  85.         NOP();
  86.         if((temp & 0x80)) //“探”最高位是否为“1”。
  87.         SDO=1;//为“0”时,直接拉低输出数据线。
  88.         else
  89.             SDO=0;
  90.         NOP();
  91.         SCK=1;                 //上升沿发送数据
  92.         NOP();               //提供一定的脉宽,一个指令周期,1us
  93.         temp<<=1;         //数据左移一位
  94.         //注这里也可以采用读函数中的写法,先将数据确定好,然后,直接产生上升沿发出去,开始还是要拉低。
  95.     }
  96.     //SDO=0;
  97.     SCK=1;
  98.     for(i=0;i<10;i++)
  99.     {
  100.         NOP();
  101.     }
  102.     for(i=0;i<8;i++)
  103.     {
  104.         SCK=0;
  105.         NOP();
  106.         SCK=1;
  107.         NOP();//这个上升沿要先写出来,如此数据才会发过来。
  108.         BUF<<=1;//一定要先,移位。不然,后移位会将正确的值扩大两倍。
  109.         BUF|=SDI;
  110.         NOP();
  111.     }
  112.     return(BUF);
  113.     //delayms(1);
  114. }

  115. */

  116. …………限于本文篇幅 主机代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
proteus+源程序.zip (40.55 KB, 下载次数: 24)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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