单片机MSP430F149DS1302读写及串口收发程序.docx
《单片机MSP430F149DS1302读写及串口收发程序.docx》由会员分享,可在线阅读,更多相关《单片机MSP430F149DS1302读写及串口收发程序.docx(20页珍藏版)》请在冰点文库上搜索。
![单片机MSP430F149DS1302读写及串口收发程序.docx](https://file1.bingdoc.com/fileroot1/2023-7/3/8b81ebd3-4069-4655-98d1-45b89befc0a3/8b81ebd3-4069-4655-98d1-45b89befc0a31.gif)
单片机MSP430F149DS1302读写及串口收发程序
/********************************************************
*文件名称:
*IIC.c
*文件说明:
*使用口线模拟IIC
*程序使用波特率为2400,程序运行时需要在pc机上使用一个串口
*接收发送程序,任意发送字符,接收的字符为十六进制时间数据
*MSP-FET430P149Demo-BasicClock,MCLKSourcedfromHFXTALXT2
*L.TCH
*Feb2007
*BuiltwithIAREmbeddedWorkbenchVersion:
3.10A
*******************************************************/
/*********************************************************/
#include
/*********************************************************
*定义
*********************************************************/
#defineRSTBIT7
#defineSDABIT6
#defineSCLKBIT5
charpbuf[7];
charclok[7]={0x16,0x15,0x14,0x13,0x12,0x04,0x07};
charcbuf;
charbbuf;
char*pda;
char*pck;
char*prg;
/************************************************
说明
************************************************/
voidPort_Init(void);
voidInit_CLK(void);
voidInit_UART0(void);
voidRST_Enable(void);
voidRST_Disable(void);
voidSCLK_HI(void);
voidSCLK_LO(void);
voidWriteByte(charnVal);
charReadByte(void);
voidWriteTo1302(charnAddr,charnVal);
charReadFrom1302(charnAddr);
voidBurstWriteTime(char*pWClock);
voidBurstReadTime(char*pRClock);
voidBurstWriteRam(char*pWReg);
voidBurstReadRam(char*pRReg);
voidSetTime(char*pClock);
voidGetTime(charpTime[]);
/***********************************************/
voidPort_Init(void)
{
P1DIR|=RST;//设置CE为输出管脚
P1DIR|=RST;//设置SCLK为输出管脚
P1DIR|=SCLK;
P2DIR|=0x02;//SetP2.1tooutputdirection
return;
}
voidInit_CLK(void)
{
unsignedinti;
BCSCTL1=0X00;//将寄存器的内容清零
//XT2震荡器开启
//LFTX1工作在低频模式
//ACLK的分频因子为1
do
{
IFG1&=~OFIFG;//清除OSCFault标志
for(i=0xFF;i>0;i--);
}
while((IFG1&OFIFG)==OFIFG);//如果OSCFault=1
BCSCTL1&=~(XT2OFF+XTS);//openXT2,LFTX2selectlowfrequency
//BCSCTL1|=RSEL0+RSEL1+RSEL2;//DCORsel=7(Freq=3200k/25摄氏度)
//BCSCTL1|=0x07;
BCSCTL2+=SELM1;//MCLK的时钟源为TX2CLK,分频因子为1
BCSCTL2+=SELS;//SMCLK的时钟源为TX2CLK,分频因子为1
return;
}
voidInit_UART0(void)
{
U0CTL=0X00;//将寄存器的内容清零
UCTL0|=SWRST;
P3SEL|=0x30;//P3.4,5=USART0TXD/RXD
ME1|=UTXE0+URXE0;//EnableUSART0TXD/RXD
UCTL0|=CHAR;//8-bitcharacter
UTCTL0|=SSEL1;//UCLK=SMCLK
UBR00=0xD3;//3.58Mhz/2400-1491
UBR10=0x05;//
UMCTL0=0x00;//nomodulation
UCTL0&=~SWRST;//InitializeUSARTstatemachine
IE1|=URXIE0;//EnableUSART0RXinterrupt
IE1&=~UTXIE0;//DisableUSARTTXinterrupt
return;
}
voidRST_Enable(void)
{
P1OUT|=RST;
return;
}
voidRST_Disable(void)
{
P1OUT&=~(RST);
return;
}
voidSCLK_HI(void)
{
P1OUT|=SCLK;
return;
}
voidSCLK_LO(void)
{
P1OUT&=~(SCLK);
return;
}
/*-------------------------------
*功能:
写入1Byte数据
*调用:
*输入:
nVal写入的数据
*返回值:
无
*------------------------------*/
voidWriteByte(charnVal)
{
chari,j;
charnTemp=nVal;
charnSend;
P1DIR|=SDA;//设置DATA为输出管脚
_NOP();
_NOP();
_NOP();
_NOP();
for(i=0;i<8;i++)//发8位,从0位开始
{
nSend=(nTemp&0x01);
if(nSend==1)
{
P1OUT|=SDA;
}
else
{
P1OUT&=~(SDA);
}
SCLK_HI();
for(j=10;j>0;j--);
SCLK_LO();
for(j=10;j>0;j--);
nTemp>>=1;//从0位开始,发8位
}
return;
}
/*--------------------------------------
*功能:
读取1Byte数据
*调用:
*输入:
*返回值:
nTemp
*------------------------------------*/
charReadByte(void)
{
charnTemp=0;
inti;
intj;
P1DIR&=~SDA;//设置DATA为输入管脚
_NOP();
_NOP();
_NOP();
_NOP();
for(i=0;i<8;i++)//接受8位
{
SCLK_HI();
for(j=10;j>0;j--);
SCLK_LO();
_NOP();
_NOP();
if(P1IN&SDA)//如果第i位是高电平置1
{
nTemp|=(0x01<
}
for(j=10;j>0;j--);
}
returnnTemp;
}
/*-----------------------------------------
*功能:
往DS1302写入1Byte数据
*调用:
*输入:
nVal写入的数据
*返回值:
无
*------------------------------------------*/
voidWriteTo1302(charnAddr,charnVal)
{
RST_Disable();
SCLK_LO();
RST_Enable();
_NOP();
_NOP();
_NOP();
_NOP();
WriteByte(nAddr);//地址,命令
WriteByte(nVal);//写1Byte数据
SCLK_HI();
RST_Disable();
return;
}
/*-----------------------------------------
*功能:
从DS1302读取1Byte数据
*调用:
*输入:
*返回值:
nDta
*-----------------------------------------*/
charReadFrom1302(charnAddr)
{
charnData;
RST_Disable();
SCLK_LO();
RST_Enable();
_NOP();
_NOP();
_NOP();
_NOP();
WriteByte(nAddr);//地址,命令
nData=ReadByte();//读1Byte数据
SCLK_HI();
RST_Disable();
cbuf=nData;//
return(nData);
}
/*-------------------------------------
*功能:
往DS1302写入时钟数据(多字节方式)
*调用:
*输入:
pClock[]:
时钟数据地址格式为:
秒分时日月星期年控制
*8Byte(BCD码)
*返回值:
无
*----------------------------------*/
voidBurstWriteTime(char*pClock)
{
chari;
WriteTo1302(0x8e,0x00);//控制命令,写操作.。
WP=0开写保护
RST_Disable();
SCLK_LO();
RST_Enable();
WriteByte(0xbe);//0xbe:
时钟多字节写命令
for(i=8;i>0;i--)//8Byte=7Byte时钟数据+1Byte控制(即写保护)
{
WriteByte(*pClock);//写1Byte数据
pClock++;
}
SCLK_HI();
RST_Disable();
return;
}
/*-----------------------------------------
*功能:
读取DS1302时钟数据(多字节方式)
*调用:
*输入:
pClock[]:
时钟数据地址格式为:
秒分时日月星期年控制
*8Byte(BCD码)
*返回值:
ucDa:
读取的数据
*---------------------------------------*/
voidBurstReadTime(char*pClock)
{
chari;
RST_Disable();
SCLK_LO();
RST_Enable();
WriteByte(0xbf);//0xbf:
时钟多字节读命令
for(i=8;i>0;i--)
{
*pClock=ReadByte();//读1Byte数据
pClock++;
}
SCLK_HI();
RST_Disable();
return;
}
/*-----------------------------------------
*功能:
往DS1302寄存器数写入数据(多字节方式)
*调用:
*输入:
pReg:
寄存器数据地址
*返回值:
无
*----------------------------------------*/
voidBurstWriteRam(char*pReg)
{
chari;
WriteTo1302(0x8e,0x00);//控制命令,WP=0,写操作
RST_Disable();
SCLK_LO();
RST_Enable();
WriteByte(0xfe);//0xfe:
寄存器数据多字节写命令
for(i=31;i>0;i--)//31Byte寄存器数据
{
WriteByte(*pReg);//写1Byte数据
pReg++;
}
SCLK_HI();
RST_Disable();
return;
}
/*------------------------------------------
*功能:
读取DS1302寄存器数据
*调用:
*输入:
pReg:
寄存器数据地址
*返回值:
无
*----------------------------------------*/
voidBurstReadRam(char*pReg)
{
chari;
RST_Disable();
SCLK_LO();
RST_Enable();
WriteByte(0xff);//0xff:
寄存器数据多字节读命令
for(i=31;i>0;i--)//31Byte寄存器数据
{
*pReg=ReadByte();//读1Byte数据
pReg++;
}
SCLK_HI();
RST_Disable();
return;
}
/*------------------------------------------
*功能:
设置初始时间(以单字节读写进行)
*调用:
*输入:
pClock[]:
初始时间地址。
初始时间格式为:
秒分时日月星期年
*7Byte(BCD码)
*返回值:
无
*-----------------------------------------*/
voidSetTime(char*pClock)//写时间寄存器,顺序是:
(1)使寄存器可写,
(2)写时间(3)写保护
//以单个字节的形式进行读写
{
chari;
charnAddr=0x80;
WriteTo1302(0x8e,0x00);//控制命令,WP=0,写操作(使时间寄存器可写)
for(i=7;i>0;i--)
{
WriteTo1302(nAddr,*pClock);//秒分时日月星期年(从80开始共写7个,每次地址+2)
pClock++;
nAddr+=2;
}
WriteTo1302(0x8e,0x80);//控制命令,WP=1,写保护?
return;
}
/*------------------------------------------
*功能:
读取DS1302当前时间(以单字节读写进行)
*调用:
*输入:
pTime[]:
保存当前时间地址。
当前时间格式为:
秒分时日月星期年
*7Byte(BCD码)
*返回值:
无
*-----------------------------------------*/
voidGetTime(charpTime[])//只读时间寄存器以单字节读写进行,连续7个
{
chari;
charnAddr=0x81;
for(i=0;i<7;i++)
{
pTime[i]=ReadFrom1302(nAddr);//格式为:
秒分时日月星期年
nAddr+=2;
}
return;
}
/*------------------------------------------------
*接收中断
*----------------------------------------------*/
#pragmavector=UART0RX_VECTOR//接收中断
__interruptvoidusart0_rx_tx(void)
{
/*chari,t;
for(t=0;t<1;t++)
{
//IFG1&=0XBF;//实际上是清URXIFG0,防止接收中断进入死循环
P2OUT^=0x02;//ToggleP2.1usingexclusive-OR
while(!
UTXIFG0);//USART0tXbufferready?
)
//GetTime(pbuf);//读1302时间
//IE1|=UTXIE0;//开发中断
for(i=0;i<7;i++)
{
TXBUF0=pbuf[i];
while((UTCTL0&0x01)!
=0x01);//等待直到没有数据发送
}
//IFG1&=0X3F;
}
*/
}
voidmain(void)
{
volatileunsignedinti;
pck=&clok[0];
pda=&pbuf[0];
WDTCTL=WDTPW+WDTHOLD;
_DINT();//offint
Init_CLK();
Port_Init();
Init_UART0();
WriteTo1302(0x8e,0x00);//控制命令,写操作.。
WP=0开写保护
WriteTo1302(0x80,0x00);//CH=0振荡器工作,并写0秒
WriteTo1302(0x82,0x01);//写1分
WriteTo1302(0x8e,0x80);//控制命令,WP=1,写保护?
_EINT();
while
(1)//等中断
{
P2OUT^=0x02;//ToggleP2.1usingexclusive-OR
i=50000;//Delay
do(i--);
while(i!
=0);
ReadFrom1302(0x81);//读秒
bbuf=(cbuf|0x70);//显示转换
cbuf=(cbuf|0x0f);
switch(cbuf)
{
case0x08:
cbuf=0x05;
break;
case0x09:
cbuf=0x06;
break;
case0x0a:
cbuf=0x07;
break;
case0x0b:
cbuf=0x08;
break;
case0x0c:
cbuf=0x09;
default:
break;
}
bbuf=(bbuf&0x0f);
cbuf=(cbuf&0x70);
cbuf=(bbuf|cbuf);
while(!
UTXIFG0);//USART0tXbufferready?
)
TXBUF0=cbuf;
while((UTCTL0&0x01)!
=0x01);//等待直到没有数据发送
i=50000;//Delay
do(i--);
while(i!
=0);
P2OUT^=0x02;//ToggleP2.1usingexclusive-OR
ReadFrom1302(0x83);//读分
bbuf=(cbuf|0x70);//显示转换
cbuf=(cbuf|0x0f);
switch(cbuf)
{
case0x08:
cbuf=0x05;
break;
case0x09:
cbuf=0x06;
break;
case0x0a:
cbuf=0x07;
break;
case0x0b:
cbuf=0x08;
break;
case0x0c:
cbuf=0x09;
default:
break;
}
bbuf=(bbuf&0x0f);
cbuf=(cbuf&0x70);
cbuf=(bbuf|cbuf);
while(!
UTXIFG0);//USART0tXbufferready?
)
TXBUF0=cbuf;
while((UTCTL0&0x01)!
=0x01);//等待直到没有数据发送
_NOP();
_NOP();
}
}
//msp430串口分收中断和发中断
//中断函数对不同的IAR版本语法上写法上有所不同
//中断矢量的定义,具体见430Fxxx的头文件详解
//DS1302应用说明:
//1、首先是写保护开,即8邢唷?
>?
(*?
'