Shift1 - sending serial data with only one wire
a typical spi interface requires two wires: SCK to transmit clock, and SDO to transmit data (out).this can be too much for chips with limited io pins (like pdiop8 or sot5 chips).
so here is an approach proposed by Roman Black that combines SCK / SDO to send serial data.
it essentially uses a r/c network to hold SDO and then quickly strobe out the clock information on the SCK line.
here is how it transmits 0x52 into a hc164:
http://cache.amobbs.com/bbs_upload782111/files_42/ourdev_658024ASLZGE.PNG
(原文件名:send1.PNG)
the transmission is spi compliant in that it sends msb first, and the data is send on sck's rising edge. here is the code for 8051 - but can be easily adapted for other mcus.
===========user code======================
#include <regx51.h> //we use keil c51
#include "gpio.h"
#include "delay.h" //we use delay
#include "send1.h" //we use send1 protocol
//hardware configuration
//end hardware configuration
void mcu_init(void) {
}
int main(void) {
mcu_init(); //reset the mcu
send1_init(); //reset send1
send1_write(0x52);
while (1) {
}
}
==========================
two routines:
1) send1_init(): reset the send1 pins. actually it is empty;
2) send1_write(): send a byte over the send1 bus. here is the header file, send1.h:
======================send1.h==================
//send1 header file
//hardware configuration
#define SEND1_PORT P2
#define SEND1_DDR P2
#define SEND1_SCO (1<<0) //send1 sck/sdo pin
#define SEND1_DLY (10) //time delay to send 1, in us - for 10k/4.7n network
//#define SEND1_DLY (20) //time delay to send 1, in us - for 10k/4.7n network
//define SEND1_DLY (10) //time delay to send 1, in ms - for 10k/47nf network
//end hardware configuration
//initialize send1
void send1_init(void);
//send a byte
void send1_write(unsigned char dat); here is the source file
===============send1.c=======================
//using 1 wire to send serial data
//msb first
//on the rising edge
#include <regx51.h> //we use keil c51
#include "gpio.h"
#include "delay.h" //we use delay
#include "send1.h" //we use send1 protocol
//hardware configuration
//end hardware configuration
//initialize send1
void send1_init(void) {
//IO_SET(SEND1_PORT, SEND1_SCO); //clear sco
//IO_OUT(SEND1_DDR, SEND1_SCO); //sco as output
}
#define send1_delay() {delay_us(SEND1_DLY);}
//send bit 1
#define send1_1() {IO_CLR(SEND1_PORT, SEND1_SCO); IO_SET(SEND1_PORT, SEND1_SCO);}
//send bit 0
#define send1_0() {IO_CLR(SEND1_PORT, SEND1_SCO); send1_delay(); IO_SET(SEND1_PORT, SEND1_SCO);}
//send a byte
void send1_write(unsigned char dat) {
unsigned char mask = 0x80; //msb first
do {
//initialize the bus - bring SCO to high
IO_SET(SEND1_PORT, SEND1_SCO); //set sco
IO_OUT(SEND1_DDR, SEND1_SCO); //sco as output
send1_delay(); //charge up the cap
if (dat & mask) send1_1() //send 1
else send1_0(); //send 0
mask = mask >> 1; //shift to the next bit
} while (mask);
} depending on user requirements, you can adjust the value of the r/c network, and then SEND1_DLY and send1_delay() accordingly.
longer SEND1_DLY or longer r/c constant gives better reliability, but slows down the speed.
typical speed? with the value given, it takes 1.5ms to send a byte, vs. 0.1ms typically using two pins. 这样弄...一旦修改频率,RC的值就得改.
某些场合还是值得的。 "一旦修改频率,RC的值就得改. "
no, if your send1_delay() routine gives the same delay duration under different cpu speed. 回复【6楼】millwood0
-----------------------------------------------------------------------
哈哈。。。还有软件呢。。俺光想着硬件了。
如果是特定的硬件时序需求,R、C固定下来后,send1_delay也是可以根据CPU频率计算出来的。
汗。。俺回的贴应该是在1楼啊。。当时没提交? 嗯学习学习。 "如果是特定的硬件时序需求,R、C固定下来后,send1_delay也是可以根据CPU频率计算出来的。 "
that's correct. all you need is for send1_delay() to be sufficiently long so that the voltage on the capacitor has been below the lowest input high.
Vih>Vcc*e(-t/(rc)).
页:
[1]