软件模拟SPI口的一些思考

[复制链接]
4021|13
 楼主| sinanjj 发表于 2007-11-29 16:59 | 显示全部楼层 |阅读模式
如果我们要把240bit的数据通过模拟SPI口传送出去,&nbsp;一般的我们定义一数组,&nbsp;把240bit的数据放在30个byte里,&nbsp;然后,&nbsp;通过<br /><br />tempi=nodeConfig[ByteCnt];<br />&nbsp;for(BitCnt=0;BitCnt!=8;BitCnt++)<br />&nbsp;&nbsp;{<br />&nbsp;&nbsp;PORTA&=0xFD;&nbsp;//1111&nbsp;1101,&nbsp;CLK=0<br />&nbsp;&nbsp;if(tempi&0x80)&nbsp;//1000&nbsp;0000<br />&nbsp;&nbsp;PORTA|=0x04;&nbsp;//0000&nbsp;0100,&nbsp;data(configuration&nbsp;word)&nbsp;output=1;&nbsp;PA2<br />&nbsp;&nbsp;else<br />&nbsp;&nbsp;PORTA&=0xFB;&nbsp;//1111&nbsp;1011,&nbsp;data(configuration&nbsp;word)&nbsp;output=0;&nbsp;PA2<br />&nbsp;&nbsp;delay_1us();<br />&nbsp;&nbsp;PORTA|=0x02;&nbsp;//0000&nbsp;0010,&nbsp;CLK=1<br />&nbsp;&nbsp;delay_1us();<br />&nbsp;&nbsp;PORTA&=0xFD;&nbsp;//CLK=0<br />&nbsp;&nbsp;tempi=tempi&lt&lt1;<br />&nbsp;&nbsp;}<br /><br />之类的代码传输给外设.&nbsp;<br /><br />但是,&nbsp;我们的编程中需要对这240个bit频繁的操作,&nbsp;最好定义成结构体,&nbsp;但是,&nbsp;结构体就不能用上面的方法模拟SPI口了,&nbsp;因为结构体中有1byte的有1bit的有2byte的,&nbsp;所以....<br /><br /><br />不知各位对此有何高见<br /><br />谢谢指点先.
computer00 发表于 2007-11-29 17:07 | 显示全部楼层

强制类型转换为数组来发不行吗?

  
xwj 发表于 2007-11-29 17:18 | 显示全部楼层

用联合或强制转换成指针操作啦

  
computer00 发表于 2007-11-29 17:26 | 显示全部楼层

按字节发送,对方按字节接收就行了

Struct&nbsp;TCB<br />{<br />int&nbsp;deadline;<br />unsighed&nbsp;state:1;&nbsp;//位域在结构体中<br />unsighed&nbsp;rt:1;&nbsp;//位域在结构体中<br />int&nbsp;sp;<br />struct&nbsp;TCB&nbsp;*prev,next;&nbsp;//结构体指针以构成链表<br />struct&nbsp;TASK&nbsp;*p_task;&nbsp;//结构体指针指向其他结构体<br />proc_t&nbsp;*do_error;<br />}TCB[n_tasks];//声明了一个Struct&nbsp;TCB结构的结构体数组<br /><br /><br /><br /><br />for(i=0;i&ltsizeof(TCB[0]);i++)<br />{<br />&nbsp;send(((unsigned&nbsp;char&nbsp;*)(&(TCB[0]))));<br />}
xwj 发表于 2007-11-29 17:34 | 显示全部楼层

是的,就如小蛋蛋所说.

  
 楼主| sinanjj 发表于 2007-11-29 21:18 | 显示全部楼层

整理了一下相关资料

变量类型转换:&nbsp;1,&nbsp;不同类型的变量运算时自动转换.&nbsp;2,&nbsp;强制类型转换<br />(类型说明符)(表达式);&nbsp;//把表达式的运算结果强制转换成类型说明符所表示的类型.<br />(float)a;&nbsp;//把a转换为实型<br />(int)(x+y);&nbsp;//类型说明符和表达式都必须加括号(单个变量可以不加括号).<br />(无论是强制转换或是自动转换,&nbsp;都只是为了本次运算的需要而对变量的数据长度进行的临时性转换,&nbsp;不改变数据说明时对该变量定义的类型)<br />3,&nbsp;指针类型强制转换:&nbsp;指针p:&nbsp;<br />(TYPE*)p;<br />这样强制类型转换的结果是一个新指针,&nbsp;该新指针的类型是TYPE*,&nbsp;它指向的类型是TYPE,&nbsp;它指向的地址就是原指针指向的地址.<br />4,&nbsp;强制转换成指针类型:&nbsp;unsigned&nbsp;int&nbsp;a;&nbsp;TYPE&nbsp;*ptr;&nbsp;a=0x0001;&nbsp;ptr=(TYPE*)a;&nbsp;//把a强制转换成指向TYPE类型的指针.&nbsp;转换过程中a的值不变,&nbsp;即(TYPE*)a表示0x0001地址开头的TYPE结构的结构体变量.&nbsp;所以,&nbsp;ptr指向的地址为0x0001.&nbsp;这是一种实现对地址直接操作的方法,&nbsp;但是注意0x0001开始处必须有TYPE结构的变量,&nbsp;不然会产生内存越界而导致错误.&nbsp;<br />5,&nbsp;指针强制类型转换:&nbsp;用新的指针类型来解析原来地址空间中的内容&nbsp;&nbsp;&nbsp;<br />如<br />struct&nbsp;aaa<br />{<br />char&nbsp;id;char&nbsp;cmd;char&nbsp;byte[4];<br />}aaa1;<br />struct&nbsp;bbb<br />{<br />char&nbsp;id;char&nbsp;cmd;char&nbsp;*ptr;<br />}bbb1;<br />运行到了程序某处,&nbsp;执行了指针强制类型转换:&nbsp;bbb1=(struct&nbsp;bbb*)aaa1;<br />假定aaa1强制类型转换前的空间的内容是<br />(struct&nbsp;aaa)<br />1byte&nbsp;&nbsp;&nbsp;&nbsp;1byte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4bytes<br />id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[4]<br />0x01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x03040506<br />强制类型转换之后,&nbsp;就要以struct&nbsp;bbb来解析该内容<br />bbb1,&nbsp;一共6bytes<br />1byte&nbsp;&nbsp;&nbsp;&nbsp;1byte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4bytes<br />id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cmd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ptr<br />0x01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x02&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0x03040506<br />原来byte[4]的内容成为ptr的内容,&nbsp;而不是byte[4]的首地址.&nbsp;即:&nbsp;ptr指向的地址为0x03040506,&nbsp;bbb1-&gtptr为地址0x03040506处存放的值.<br />
 楼主| sinanjj 发表于 2007-11-29 21:24 | 显示全部楼层

00所说, 本人还不能完全理解, 我要花些时间研究(佩服00)

<br />for(i=0;i&ltsizeof(TCB[0]);i++)<br />{<br />send(((unsigned&nbsp;char&nbsp;*)(&(TCB[0]))));<br />}
qqqq4com 发表于 2007-11-29 21:29 | 显示全部楼层

中国商务导航网

这里有大量的电子信息&nbsp;中国商务导航网 <br /> 相关链接:<a href='http://www.qqqq4.com/'>http://www.qqqq4.com/</a>
 楼主| sinanjj 发表于 2007-11-29 21:33 | 显示全部楼层

理论上很好理解, 我要用编译器验证一下(感觉很玄啊)

((unsigned&nbsp;char&nbsp;*)(&(TCB[0])))<br />&nbsp;---数组,&nbsp;前边括号里的一定是数组指针<br />(&(TCB[0]))---TCB的地址(TCB[]--直接能转成数组么??)<br />(unsigned&nbsp;char&nbsp;*)&nbsp;--把TCB的地址变成一个指向char的地址.<br /><br />把结构体强制成数组了.&nbsp;<br /><br />我试试
computer00 发表于 2007-11-29 21:48 | 显示全部楼层

呵呵,对方接收时也使用同样的结构体

按照同样的顺序放进去,那么结果就刚好对上了。
 楼主| sinanjj 发表于 2007-11-29 22:59 | 显示全部楼层

不知什么原因, 不能编译通过.测试代码如下(ICC编译)

//ICC-AVR&nbsp;application&nbsp;builder&nbsp;:&nbsp;2007-11-29&nbsp;22:23:09<br />//&nbsp;Target&nbsp;:&nbsp;M16<br />//&nbsp;Crystal:&nbsp;8.0000Mhz<br /><br />#include&nbsp;&ltiom16v.h&gt<br />#include&nbsp;&ltmacros.h&gt<br /><br />void&nbsp;port_init(void)<br />{<br />&nbsp;PORTA&nbsp;=&nbsp;0x00;<br />&nbsp;DDRA&nbsp;&nbsp;=&nbsp;0x00;<br />&nbsp;PORTB&nbsp;=&nbsp;0x00;<br />&nbsp;DDRB&nbsp;&nbsp;=&nbsp;0x00;<br />&nbsp;PORTC&nbsp;=&nbsp;0x00;&nbsp;//m103&nbsp;output&nbsp;only<br />&nbsp;DDRC&nbsp;&nbsp;=&nbsp;0x00;<br />&nbsp;PORTD&nbsp;=&nbsp;0x00;<br />&nbsp;DDRD&nbsp;&nbsp;=&nbsp;0x00;<br />}<br /><br />//call&nbsp;this&nbsp;routine&nbsp;to&nbsp;initialize&nbsp;all&nbsp;peripherals<br />void&nbsp;init_devices(void)<br />{<br />&nbsp;//stop&nbsp;errant&nbsp;interrupts&nbsp;until&nbsp;set&nbsp;up<br />&nbsp;CLI();&nbsp;//disable&nbsp;all&nbsp;interrupts<br />&nbsp;port_init();<br /><br />&nbsp;MCUCR&nbsp;=&nbsp;0x00;<br />&nbsp;GICR&nbsp;&nbsp;=&nbsp;0x00;<br />&nbsp;TIMSK&nbsp;=&nbsp;0x00;&nbsp;//timer&nbsp;interrupt&nbsp;sources<br />&nbsp;SEI();&nbsp;//re-enable&nbsp;interrupts<br />&nbsp;//all&nbsp;peripherals&nbsp;are&nbsp;now&nbsp;initialized<br />}<br /><br />main()<br />{<br />unsigned&nbsp;char&nbsp;aa[34];<br />unsigned&nbsp;char&nbsp;i;<br />struct&nbsp;TCB<br />&nbsp;{<br />&nbsp;int&nbsp;deadline;<br />&nbsp;unsigned&nbsp;state:1;&nbsp;//位域在结构体中<br />&nbsp;unsigned&nbsp;rt:1;&nbsp;//位域在结构体中<br />&nbsp;int&nbsp;sp;<br />&nbsp;struct&nbsp;TCB&nbsp;*next;&nbsp;//结构体指针以构成链表<br />&nbsp;}TCB[5];//声明了一个Struct&nbsp;TCB结构的结构体数组<br />//把结构体TCB[0]强制转换成unsigned&nbsp;char数组:<br />for(i=0;i&ltsizeof(TCB[0]);i++)&nbsp;//sizeof():&nbsp;求数据类型所占的byte数,&nbsp;sizeof(TCB[0])代表TCB[0]占的byte数.<br />&nbsp;{&nbsp;<br />&nbsp;aa=(unsigned&nbsp;char*)(&(TCB[0])));<br />&nbsp;}&nbsp;//send(unsigned&nbsp;char&nbsp;temp):&nbsp;发送temp到目的地.&nbsp;(&(TCB[0]))代表结构体TCB[0]的起始地址,&nbsp;(unsigned&nbsp;char&nbsp;*)把TCB[0]的起始地址强制转换成一个指向unsigned&nbsp;char类型的指针.&nbsp;存在,&nbsp;一般的数组为aa,&nbsp;aa表示数组的起始地址,&nbsp;而((unsigned&nbsp;char&nbsp;*)(&(TCB[0])))正好是一个指向unsigned&nbsp;char类型的指针,&nbsp;符合数组形式.&nbsp;<br />}<br /><br />
computer00 发表于 2007-11-29 23:14 | 显示全部楼层

晕...照着抄下来也错?少了一个(......

  
赤铸 发表于 2007-11-30 00:27 | 显示全部楼层

人嘛,需要高级思想,也需要低级趣味

LZ&nbsp;之所以觉得难以理解就是该低级的时候低不下来<br /><br />数据的“意义”是人为赋予的,你认为这个是TCB.state,那个是什么指针,<br />但在数据通信的层次,那就全是比特、字节……<br /><br />通信的基本思想就是“分层”,在传输这一层,就应该不管内容,只管按字节拷贝,拷贝过去原样恢复就是了
567 发表于 2007-11-30 12:09 | 显示全部楼层

要效率还是通用性

要效率,就使用联合、指针、类型转换等。<br /><br />要通用性、可移植性,就用&nbsp;与&nbsp;或&nbsp;等操作拷贝到另一个数组中再处理。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

456

主题

6299

帖子

25

粉丝
快速回复 在线客服 返回列表 返回顶部