基于MSP430F149单片机驱动DS2762读写操作C语言程序,能够对按键或着其他信号响应,读出电流以及电压量,并进行相应处理。 //#include <msp430x14x.h> #define uchar unsigned char #define uint unsigned int uint A,B,C,D,E,F,G,H,I,J;//此处对io430x14x中的宏定义C进行了注释,需注意 #define IO_OUT P3DIR |= BIT0; #define IO_INP P3DIR &= ~BIT0; uint data; /****************************************************************************** 对读写时间进行规范化 初始调试采用standard=1的参数 // Pause for exactly 'tick' number of ticks = 0.25us 实际测的A延时14Us B125US ******************************************************************************/ void SetSpeed(uint standard) { // Adjust tick values depending on speed if (standard) { // Standard Speed A = 6 * 4 / 2; B = 64 * 4 / 2; C = 60 * 4 / 2; D = 10 * 4 / 2; E = 9 * 4 / 2; F = 55 * 4 / 2; G = 0 / 2; H = 480 * 4 / 2; I = 70 * 4 / 2; J = 410 * 4 / 2; } else { // Overdrive Speed A = 1.5 * 4; B = 7.5 * 4; C = 7.5 * 4; D = 2.5 * 4; E = 0.75 * 4; F = 7 * 4; G = 2.5 * 4; H = 70 * 4; I = 8.5 * 4; J = 40 * 4; } } /****************************************************************************** 延时程序 注意,需要选用8M晶振,时钟周期125ns ******************************************************************************/ void tickDelay(uint tick) // Implementation is platform specific { for(;tick>0;tick--); } /****************************************************************************** 主机复位脉冲 当接收结果result为0时,表明从机应答 ******************************************************************************/ uchar OWTouchReset(void) { uchar result; IO_OUT; tickDelay(G); P30 = 0; // Drives DQ low tickDelay(H); P30 = 1; // Releases the bus tickDelay(I); IO_INP; result = P3IN & 0X01; // Sample for presence pulse from slave tickDelay(J); // Complete the reset sequence recovery return result; // Return sample presence pulse result } /****************************************************************************** 像写DS2762写入一位 Send a 1-Wire write bit. Provide 10us recovery time. ******************************************************************************/ void OWWriteBit(uchar bit) { if (bit) { // Write '1' bit P30 = 0; // Drives DQ low tickDelay(A); P30 = 1; // Releases the bus tickDelay(B); // Complete the time slot and 10us recovery } else { // Write '0' bit P30 = 0; // Drives DQ low tickDelay(C); P30 = 1; // Releases the bus tickDelay(D); } } /****************************************************************************** 从DS2762读出一位 Read a bit from the 1-Wire bus and return it. Provide 10us recovery time. ******************************************************************************/ uchar OWReadBit(void) { uchar result; P30 = 0; // Drives DQ low tickDelay(A); P30 = 1; // Releases the bus tickDelay(E); result = P3IN & 0X01; // Sample the bit value from the slave tickDelay(F); // Complete the time slot and 10us recovery return result; } /****************************************************************************** 像写DS2762写入一个字节 Send a 1-Wire write . Provide 10us recovery time. DS2762特性发送所有的命令和数据都是字节的低位在前,这与多数串行通信格式相反 ******************************************************************************/ void OWWriteByte(uchar data) { uchar loop; // Loop to write each bit in the byte, LS-bit first for (loop = 0; loop < 8; loop++) { OWWriteBit(data & 0x01); // shift the data byte for the next bit data >>= 1; } } /****************************************************************************** 从DS2762中读一个字节 ******************************************************************************/ uchar OWReadByte(void) { uchar loop, result=0; for (loop = 0; loop < 8; loop++) { // shift the result to get it ready for the next bit result >>= 1; // if result is one, then set MS bit if (OWReadBit()) result |= 0x80; } return result; } /****************************************************************************** 发送字符函数 按照论文图时序进行的操作 目前不清楚连续读需要通过测试进行优化。 方案一:发出读命令 发出一个地址 读两次 应该是正确的 方案二:发出读命令 发出两个地址 读两次 ******************************************************************************/ uint readvoltage(void) { uchar j = 1; unsigned char volhigh,vollow; while(j) //检查2762是否应答 { j = OWTouchReset(); } OWWriteByte(0xcc); // OWWriteByte(0x69); OWWriteByte(0x0c); vollow = OWReadByte(); volhigh = OWReadByte(); return ((volhigh<<8)|(vollow)); //将两个字节进行合并 } /****************************************************************************** 时钟初始化 注意,需要选用8M晶振,时钟周期125ns ******************************************************************************/ void Init_clk(void) {unsigned char i; //时基模块的时钟设置 //单片机上电时,MCLK主时钟的源默认选择为DCO提供.F1系列DCO默认800KHZ. //ACLK辅助时钟默认为XT1,XT1一般接32768HZ晶体. //SMCLK子时钟默认为DCO,同样是800KHZ. //XT2需要人为开启,并要检测其开启是否成功. BCSCTL1 &= ~(XT2OFF + XTS); //启动XT2高速时钟模块 BCSCTL2 |= SELM1; //MCLK主时钟选XT2为时钟源.TX2输入不分频. BCSCTL2 &= ~SELS; //SMCLK选为DCO为时钟源.(参考) //刚才开启了XT2,需要一定时间XT2才进入稳定状态.所以需要等待并检测稳定状态. //通常采用do...for语法,这是TI推荐的程序写法 do { IFG1 &=~OFIFG; //清OSCFault 标志 for(i=0xff;i>0;i--) //延时等待其开启稳定 ; } while((IFG1 & OFIFG) !=0); //检查OSCFault标志位是否为0,若为0则表示XT2开启稳定. //否则一直等下去... } /****************************************************************************** 主函数 注意,需要选用8M晶振,时钟周期125ns ******************************************************************************/ void main() { WDTCTL = WDTPW | WDTHOLD; // 停止看门狗 Init_clk(); SetSpeed(1); while(1) { data = readvoltage(); } }