IO口模拟SPI总线问题

请教各位老大,如下是网络上找的IO口模拟SPI总线发送接收数据的程序,已知从设备上升沿采集数据,下降沿输出数据。有几个问题不明白,用红色标出来了,请老大指点一下,谢谢!
INT8U SpiTxRxByte(INT8U dat)
{
INT8U i,temp;
temp = 0; 
SCK = 0;                  //已知从设备上升沿采集。时钟置低,准备发送一BIT数据
for(i=0; i<8; i++)
{
  if(dat & 0x80)
  {
         MOSI = 1;        //数据已经准备好
  }
  else MOSI = 0;
  dat <<= 1;
  SCK = 1;                //时钟置高,制造一个上升沿,数据打入从设备
  _nop_;
  _nop_;
  _nop_;
  _nop_;
  temp <<= 1;       //这里开始不明白了,怎么没有制造下降沿就读从设备的数据呢。从设备是下降沿才出数据的啊。我感觉是"temp<<1;"应该放在SCK=0之 
if(MISO)temp++;    //后才对
  SCK = 0;
  _nop_;
  _nop_; 
}

return temp;
}

请老大解释一下为什么这样写,谢谢了哈!

时钟时钟程序色标

满意回复

+10

NE5532 查看完整内容

呵呵,这么高的分哪,给我吧,我告诉你咋回事。 1.从图上看出来,CSn拉低以后,MISO的第一个BIT就已经上线了,所以说这个时序严格来说在读“上一个”下降沿送出 ...

+6

sunhq02 查看完整内容

NE5532说的第三点是对的

+5

airwill 查看完整内容

就是为了符合 下面那张图的时序要求呀

+5

dqyubsh 查看完整内容

SPI有几种类型的,不一定别人的程序刚好满足你的要求。看看别人的死路,自己写一个好了。

+5

billyliang89 查看完整内容

根据你所提供的图“SO”那一行,输出数据也是上升沿锁存,即上升沿使设备锁存MOSI的数据的同时在MISO上送出数据,懂了没? ...

+5

sunhq02 查看完整内容

SPI的时序虽然是那样子没错 但是作为主设备,时序的控制权在主设备手里 从设备遵守的原则是,在主设备时钟前沿发出后的一定时间之内准备好数据 ,并在主设备时钟 ...

+5

sunhq02 查看完整内容

第2点,那个数据并不是一直在线上 SPI的协议规定从设备有义务在时钟后沿维持数据一段时间,但不是一直都在 并不一定维持到时钟前沿 ...

+5

yewuyi 查看完整内容

呵呵,这种东西如果对着时序表还看不明白,就直接打屁股10下把

+4

amwrdfe 查看完整内容

i2c,uart,对着时序图来搞,没什么难的。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册  手机登录

x

相关帖子

On My  Way!

 回复 收藏 分享 淘帖 

举报

  

airwill

     

338

主题

1万

帖子

4万

积分

版主

---------------------

专家等级:

结帖率:96%

打赏:0.00

受赏:58.00

沙发

 发表于 2012-2-10 16:40 | 只看该作者 |返回版面

就是为了符合 下面那张图的时序要求呀

欢迎进入 TI 模拟技术论坛

 回复 

举报

  

dqyubsh

44

主题

2236

帖子

7012

积分

高级工程师

专家等级:

结帖率:100%

板凳

 发表于 2012-2-10 16:47 | 只看该作者 |返回版面

SPI有几种类型的,不一定别人的程序刚好满足你的要求。看看别人的死路,自己写一个好了。

yubsh@263.net

 回复 

举报

  

billyliang89

0

主题

1

帖子

3

积分

实习生

专家等级:

结帖率:0%

地板

 发表于 2012-3-3 12:37 | 只看该作者 |返回版面

根据你所提供的图“SO”那一行,输出数据也是上升沿锁存,即上升沿使设备锁存MOSI的数据的同时在MISO上送出数据,懂了没?

21ic公开课新版上线!部分课程免费试看。还有限量优惠券可领,先到先得!http://open.21ic.com

 回复 

举报

  

sunhq02

4

主题

524

帖子

1610

积分

助理工程师

专家等级:

结帖率:100%

打赏:0.00

受赏:18.00

5楼

 发表于 2012-3-3 21:04 | 只看该作者 |返回版面

SPI的时序虽然是那样子没错
但是作为主设备,时序的控制权在主设备手里
从设备遵守的原则是,在主设备时钟前沿发出后的一定时间之内准备好数据
,并在主设备时钟后沿发出后一定时间之内保持数据
,也就是说,主设备时钟后沿前后的这段时间里面,读从设备数据,都是安全的
,前一个指令或者后一个指令并没有关系

21ic公开课新版上线!部分课程免费试看。还有限量优惠券可领,先到先得!http://open.21ic.com

 回复 

举报

  

NE5532

      

159

主题

1万

帖子

5万

积分

版主

专家等级:

结帖率:97%

打赏:0.00

受赏:38.00

6楼

 发表于 2012-3-3 21:10 | 只看该作者 |返回版面

呵呵,这么高的分哪,给我吧,我告诉你咋回事。

1.从图上看出来,CSn拉低以后,MISO的第一个BIT就已经上线了,所以说这个时序严格来说在读“上一个”下降沿送出的数据。
2.既然数据时在下降沿上线,那么没有发生“这一个”下降沿之前,上一个数据一直在线上。所以只要在上升沿之前读数都可以。
3.不知道这个程序用的啥单片机,多高频率,但是写程序的这个人明显没搞过汇编,最后两个NOP根本不需要,“return temp;”编译出来,加上下一次的调用语句,绝对不止4条汇编语句。而且很少见到什么单片机端口速度能超过SPI的(主频几十M的哪种除外)

††††看NE5532教学视频,炼就工程技术研发功力††††††††††
《跟我学DC-DC电源管理技术》【从只会写软件成长为软硬兼施】
《印刷电路板设计进阶》【12年一线设计经验大放送】
《印刷电路板设计基础》【新手别怕,老工程师带你入门!】

 回复 

举报

  

sunhq02

4

主题

524

帖子

1610

积分

助理工程师

专家等级:

结帖率:100%

打赏:0.00

受赏:18.00

7楼

 发表于 2012-3-3 23:19 | 只看该作者 |返回版面

NE5532说的第三点是对的

21ic公开课新版上线!部分课程免费试看。还有限量优惠券可领,先到先得!http://open.21ic.com

 回复 

举报

  

sunhq02

4

主题

524

帖子

1610

积分

助理工程师

专家等级:

结帖率:100%

打赏:0.00

受赏:18.00

8楼

 发表于 2012-3-3 23:23 | 只看该作者 |返回版面

第2点,那个数据并不是一直在线上
SPI的协议规定从设备有义务在时钟后沿维持数据一段时间,但不是一直都在
并不一定维持到时钟前沿

21ic公开课新版上线!部分课程免费试看。还有限量优惠券可领,先到先得!http://open.21ic.com

 回复 

举报

  

yewuyi

     

1408

主题

1万

帖子

7万

积分

版主

专家等级:

结帖率:59%

9楼

 发表于 2012-3-4 11:34 | 只看该作者 |返回版面

呵呵,这种东西如果对着时序表还看不明白,就直接打屁股10下把

一:我的回帖多数只是猜测/估计/想象,建立在我现有知识结构的理解和分析上,多数都没有动手实际检验过,请斟酌采纳.
二:若对我的技术类主帖或回帖有异议,欢迎讨论,拒绝过激攻击或辱骂,否则全站追杀屏蔽发帖,后果自负.
三:对本人的其它意见,请直接向站长投诉,勿使用站内短信骚扰/挑衅/辱骂,否则将全站追杀屏蔽发帖,后果自负.

 回复 

举报

  

amwrdfe

30

主题

730

帖子

2377

积分

初级工程师

专家等级:

结帖率:33%

打赏:8.88

受赏:0.00

10楼

 发表于 2012-3-4 13:22 | 只看该作者 |返回版面

i2c,uart,对着时序图来搞,没什么难的。

21ic公开课新版上线!部分课程免费试看。还有限量优惠券可领,先到先得!http://open.21ic.com

 回复 

举报

  

guess

0

主题

1

帖子

3

积分

实习生

专家等级:

结帖率:0%

11楼

 发表于 2012-10-9 15:42 | 只看该作者 |返回版面

学习了 正在学习中~

21ic公开课新版上线!部分课程免费试看。还有限量优惠券可领,先到先得!http://open.21ic.com

 回复 

举报

  

dlyt_test001

0

主题

255

帖子

775

积分

高级技术员

专家等级:

结帖率:50%

12楼

 发表于 2012-10-9 16:11 | 只看该作者 |返回版面

最好做个通用的,定义一个数据结构吧!上升沿还是下降沿有效可设置;
附图上的所有时间间隔可设置。
:lol

兼容PEAK CAN;32路模拟量信号发生器;串口转TTL/STC下载模块/刷机模块;淘宝上搜索“MD13213”“MD21T22”

 回复 

举报

  

reduct

0

主题

6

帖子

18

积分

实习生

专家等级:

结帖率:0%

13楼

 发表于 2015-1-7 19:03 | 只看该作者 |返回版面

人家写的这个程序其实没什么问题的,tem<<1将最低位报持为0,如果放在SCK=0之后的话,就少了一个位了。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: BL0939是一款数字温湿度传感器,通常使用SPI接口与主控芯片通信。下面是一个使用C语言模拟BL0939的SPI驱动的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #define SPI_MODE 0 /* SPI模式,0表示模式0,CPOL=0,CPHA=0 */ /* 模拟SPI总线IO口 */ #define MOSI_PIN 1 /* MOSI口 */ #define MISO_PIN 2 /* MISO口 */ #define SCK_PIN 3 /* 时钟口 */ #define CS_PIN 4 /* 片选口 */ /* 定义BL0939寄存器地址 */ #define BL0939_TEMPERATURE_REG 0x00 #define BL0939_HUMIDITY_REG 0x01 /* 模拟SPI总线传输一个字节 */ uint8_t spi_transfer(uint8_t data) { uint8_t recv_data = 0; int i; for (i = 7; i >= 0; i--) { /* 先将时钟置低 */ digitalWrite(SCK_PIN, 0); /* 将数据写入MOSI口 */ digitalWrite(MOSI_PIN, (data >> i) & 1); /* 模拟SPI传输延迟 */ delay(1); /* 拉高时钟,读取MISO口的数据 */ recv_data |= digitalRead(MISO_PIN) << i; digitalWrite(SCK_PIN, 1); /* 模拟SPI传输延迟 */ delay(1); } return recv_data; } /* 从BL0939读取温度数据 */ float bl0939_read_temperature() { uint8_t tx_data[3] = {0x03, BL0939_TEMPERATURE_REG, 0x00}; uint8_t rx_data[3]; /* 拉低片选口 */ digitalWrite(CS_PIN, 0); /* 发送读取温度命令和寄存器地址 */ int i; for (i = 0; i < 3; i++) { spi_transfer(tx_data[i]); } /* 接收温度数据 */ for (i = 0; i < 3; i++) { rx_data[i] = spi_transfer(0); } /* 拉高片选口 */ digitalWrite(CS_PIN, 1); /* 计算温度值 */ int16_t temp_raw = (rx_data[1] << 8) | rx_data[2]; return (float)temp_raw / 100.0; } /* 从BL0939读取湿度数据 */ float bl0939_read_humidity() { uint8_t tx_data[3] = {0x03, BL0939_HUMIDITY_REG, 0x00}; uint8_t rx_data[3]; /* 拉低片选口 */ digitalWrite(CS_PIN, 0); /* 发送读取湿度命令和寄存器地址 */ int i; for (i = 0; i < 3; i++) { spi_transfer(tx_data[i]); } /* 接收湿度数据 */ for (i = 0 ### 回答2: 在C语言中实现BL0939的模拟IO口的SPI驱动,可以采用以下步骤: 1.定义必要的引脚和寄存器的宏: 首先,我们需要定义与BL0939连接的引脚和相关寄存器的宏。这些宏将帮助我们在代码中方便地访问这些引脚和寄存器。 2.编写初始化函数: 初始化函数应包含引脚和寄存器的初始化,以及SPI的设置。这些包括设置引脚为输出或输入,配置SPI控制器的参数(如数据位数、时钟速度等)。 3.编写发送数据函数: 发送数据函数用于向BL0939写入数据。首先,我们将写入片选信号使BL0939响应。然后,我们可以使用SPI控制器发送数据。 4.编写接收数据函数: 接收数据函数用于从BL0939读取数据。首先,我们将写入片选信号使BL0939响应。然后,我们可以使用SPI控制器接收数据。 5.编写其他必要的功能函数: 根据BL0939的需求,可能还需要编写其他的功能函数。这些函数可以包括设置寄存器、读取状态等。 6.编写主函数: 在主函数中,我们可以使用上述编写的函数进行测试。我们可以编写代码以模拟与BL0939的交互,例如设置寄存器的值并读取其状态。 需要注意的是,由于无法直接访问硬件,我们在编写完整代码后,可以使用模拟器或硬件评估板进行测试。此外,还应仔细阅读BL0939的数据手册以了解其具体的IO口和SPI驱动要求。 ### 回答3: BL0939是一种模拟IO口的SPI(Serial Peripheral Interface)驱动芯片。要用C语言实现BL0939的模拟IO口的SPI驱动,首先需要了解BL0939的通信协议和功能。 BL0939通信协议基于SPI的主从模式,其中主设备发送的数据帧由8位控制字和8位数据字组成,从设备通过IO口进行通信。下面是一个简单的C语言示例代码,展示了如何实现BL0939的模拟IO口的SPI驱动。 ```c #include <stdio.h> #include <wiringPi.h> // 定义BL0939的IO口 #define BL0939_CS 10 #define BL0939_CLK 11 #define BL0939_IN 12 #define BL0939_OUT 13 // 初始化BL0939的IO口 void bl0939_init() { wiringPiSetup(); pinMode(BL0939_CS, OUTPUT); pinMode(BL0939_CLK, OUTPUT); pinMode(BL0939_IN, INPUT); pinMode(BL0939_OUT, OUTPUT); } // 发送数据帧到BL0939 void bl0939_send_frame(unsigned char control, unsigned char data) { digitalWrite(BL0939_CS, LOW); // 使能BL0939 // 发送控制字 for (int i = 7; i >= 0; i--) { digitalWrite(BL0939_CLK, LOW); // 下降沿时发送位 digitalWrite(BL0939_OUT, (control >> i) & 0x01); digitalWrite(BL0939_CLK, HIGH); // 上升沿时采样位 } // 发送数据字 for (int i = 7; i >= 0; i--) { digitalWrite(BL0939_CLK, LOW); // 下降沿时发送位 digitalWrite(BL0939_OUT, (data >> i) & 0x01); digitalWrite(BL0939_CLK, HIGH); // 上升沿时采样位 } digitalWrite(BL0939_CS, HIGH); // 禁止BL0939 } int main() { bl0939_init(); // 初始化BL0939的IO口 unsigned char control = 0x01; // 控制字 unsigned char data = 0x55; // 数据字 bl0939_send_frame(control, data); // 发送数据帧到BL0939 return 0; } ``` 在上述示例代码中,首先定义了BL0939的IO口引脚,并在`bl0939_init`函数中进行了初始化。然后在`bl0939_send_frame`函数中对控制字和数据字进行SPI通信,按位发送位和采样位。 在`main`函数中,定义了控制字和数据字,并调用`bl0939_send_frame`函数发送数据帧到BL0939。 需要注意的是,以上代码仅为示例,实际使用时还需要根据具体的硬件平台及接线进行适配和调整。同时还需要根据BL0939的功能文档,结合具体的需求进行更详细的代码编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值