| 
 
| 我在用430f249,oled,ds3232,调试当前时间显示模块,可是读出来的是BCD码,读出来的数据没问题,就是不知道怎么转换才能在oled上显示出来,oled是ssd1305驱动,2.23寸,128*32,大神们帮我看看吧,程序怎么改一下。我的程序如下,数据定义被我删除了。 #include <msp430x24x.h> //声明库
 
 uchar Disp[6]={0};
 float Tempreture=0;
 void OLED_Port_Initial(void);
 void OLED_Write_Comm(uchar comm);
 
 //////////////////////////////////////////////
 ///////////      延时函数      //////////////
 ////////////////////////////////////////////
 void Delay_Ms(uint m)
 {
 uint i,j;
 for(i=0;i<m;i++)
 {
 for(j=0;j<121;j++)
 {;}
 }
 }
 void Init_IO()
 {
 WDTCTL = WDTPW+WDTHOLD;                   //停止看门狗
 P4DIR=0Xff;//设置P4口为输出
 P4OUT=0xff;//P4口置高
 P5DIR=0Xff;//设置P5口为输出
 P5OUT=0xff;//P5口置高
 P6DIR=0Xff;//设置P6口为输出
 P6OUT=0xff;//P6口置高
 }
 void delay_us(uint x)
 {
 x=x*1;
 while(--x);
 }
 void start()  //开始信号
 {
 SET_SDA;
 delay_us(2);
 SET_SCL;
 delay_us(2);
 CLR_SDA;
 delay_us(2);
 delay_us(2);
 }
 void stop()   //停止
 {
 CLR_SDA;
 delay_us(2);
 SET_SCL;
 delay_us(2);
 SET_SDA;
 delay_us(2);
 }
 void respons()  //应答
 {
 uint j=0;
 P6DIR=0Xfd; //设置P6.1为输入口
 P6REN|=0x02;//允许P6.1口上下拉功能
 P6OUT|=0x02;//P6.1为上拉
 SET_SCL;
 delay_us(2);
 while((SDA_DATA_val)&&(j<250))//
 {
 j++;
 }
 P6DIR=0Xff;//设置P1口为输出,也就是把P1.4功能从输入换为输出
 CLR_SCL;
 delay_us(2);
 }
 void Ack_I2c()// 回应ACK
 {
 CLR_SDA;
 delay_us(2);
 SET_SCL;
 delay_us(2);                    /*清时钟线,钳住I2C总线以便继续接收*/
 CLR_SCL;
 delay_us(2);
 }
 void NO_Ack_I2c()//非应答
 {
 SET_SDA;
 delay_us(2);
 SET_SCL;
 delay_us(2);
 CLR_SCL;
 delay_us(2);
 }
 void write_byte(uchar date)//写一字节数据
 {
 uchar i=0,temp;
 temp=date;
 for(i=0;i<8;i++)
 {
 CLR_SCL;
 delay_us(2);
 if(temp&0x80)//如果最高位为1则拉高数据线,否则拉低数据线
 SET_SDA;
 else
 CLR_SDA;
 temp=temp<<1;
 delay_us(2);
 SET_SCL;
 delay_us(2);
 CLR_SCL;
 delay_us(2);
 }
 CLR_SCL;
 delay_us(2);
 SET_SDA;
 delay_us(2);
 }
 uchar read_byte()//对一字节数
 {
 uchar i,k=0;
 CLR_SCL;
 delay_us(2);
 SET_SDA;
 P6DIR=0Xfd;
 P6REN=0x02;
 P6OUT=0x02;
 delay_us(2);
 for(i=0;i<8;i++)
 {
 SET_SCL;
 delay_us(20);
 k*=2;
 if(SDA_DATA_val)
 k=k+1;
 CLR_SCL;
 delay_us(2);
 }
 P6DIR=0Xff;
 return k;
 }
 uint MLX90614_Read(uchar command)//读出温度数据
 {
 uchar d0,d1;
 uchar ddd;
 start();
 write_byte(SLAVE_ADDR_WR);
 respons();
 write_byte(command);
 respons();
 start();
 write_byte(SLAVE_ADDR_RD);
 respons();
 d0=read_byte();
 Ack_I2c();
 d1=read_byte();
 Ack_I2c();
 ddd=read_byte();
 NO_Ack_I2c();
 stop();
 return (d1<<8|d0);
 }
 
 /************DS3231********************/
 void delay_us_DS3231(uint x)
 {
 x=x*1;
 while(--x);
 }
 void start_DS3231()  //开始信号
 {
 SET_SDA_DS3231;
 delay_us_DS3231(2);
 SET_SCL_DS3231;
 delay_us_DS3231(2);
 CLR_SDA_DS3231;
 delay_us_DS3231(2);
 delay_us_DS3231(2);
 }
 void stop_DS3231()   //停止
 {
 CLR_SDA_DS3231;
 delay_us_DS3231(2);
 SET_SCL_DS3231;
 delay_us_DS3231(2);
 SET_SDA_DS3231;
 delay_us_DS3231(2);
 }
 void respons_DS3231()  //应答
 {
 uint j=0;
 P6DIR=0X7f; //设置P6.7为输入口
 P6REN|=0x80;//允许P6.7口上下拉功能
 P6OUT|=0x80;//P6.1为上拉
 SET_SCL_DS3231;
 delay_us_DS3231(2);
 while((SDA_DATA_val_DS3231)&&(j<250))//
 {
 j++;
 }
 P6DIR=0Xff;//设置P1口为输出,也就是把P1.4功能从输入换为输出
 CLR_SCL_DS3231;
 delay_us_DS3231(2);
 }
 void Ack_I2c_DS3231()// 回应ACK
 {
 CLR_SDA_DS3231;
 delay_us_DS3231(2);
 SET_SCL_DS3231;
 delay_us_DS3231(2);                    /*清时钟线,钳住I2C总线以便继续接收*/
 CLR_SCL_DS3231;
 delay_us_DS3231(2);
 }
 void NO_Ack_I2c_DS3231()//非应答
 {
 SET_SDA_DS3231;
 delay_us_DS3231(2);
 SET_SCL_DS3231;
 delay_us_DS3231(2);
 CLR_SCL_DS3231;
 delay_us_DS3231(2);
 }
 void write_byte_DS3231(uchar date)//写一字节数据
 {
 uchar i=0,temp;
 temp=date;
 for(i=0;i<8;i++)
 {
 CLR_SCL_DS3231;
 delay_us_DS3231(2);
 if(temp&0x80)//如果最高位为1则拉高数据线,否则拉低数据线
 SET_SDA_DS3231;
 else
 CLR_SDA_DS3231;
 temp=temp<<1;
 delay_us(2);
 SET_SCL_DS3231;
 delay_us(2);
 CLR_SCL_DS3231;
 delay_us(2);
 }
 CLR_SCL_DS3231;
 delay_us_DS3231(2);
 SET_SDA_DS3231;
 delay_us_DS3231(2);
 }
 uchar read_byte_DS3231()//对一字节数
 {
 uchar i,k=0;
 CLR_SCL_DS3231;
 delay_us_DS3231(2);
 SET_SDA_DS3231;
 P6DIR=0X7f;
 P6REN=0x80;
 P6OUT=0x80;
 delay_us_DS3231(2);
 for(i=0;i<8;i++)
 {
 SET_SCL_DS3231;
 delay_us_DS3231(20);
 k*=2;
 if(SDA_DATA_val_DS3231)
 k=k+1;
 CLR_SCL_DS3231;
 delay_us_DS3231(2);
 }
 P6DIR=0Xff;
 return k;
 }
 
 
 uchar BCD2HEX(uchar val)    //BCD转换为Byte
 {
 uchar temp;
 temp=val&0x0f;
 val>>=4;
 val&=0x0f;
 val*=10;
 temp+=val;
 
 return temp;
 }
 
 uchar HEX2BCD(uchar val)    //B码转换为BCD码
 {
 uchar i,j,k;
 i=val/10;
 j=val;
 k=j+(i<<4);
 return k;
 }
 uint Read_DS3231(uchar command)//读出温度数据
 {
 uchar d0,d1;
 uchar ddd_DS3231;
 start_DS3231();
 write_byte_DS3231(SLAVE_ADDR_WR_DS3231);
 respons_DS3231();
 write_byte_DS3231(command);
 respons_DS3231();
 start_DS3231();
 write_byte_DS3231(SLAVE_ADDR_RD_DS3231);
 respons_DS3231();
 d0=read_byte_DS3231();
 Ack_I2c_DS3231();
 d1=read_byte_DS3231();
 Ack_I2c_DS3231();
 ddd_DS3231=read_byte_DS3231();
 NO_Ack_I2c_DS3231();
 stop_DS3231();
 return (d1<<8|d0);
 }
 
 void Single_Write(unsigned char address, unsigned char thedata)
 {
 start_DS3231();//启动
 write_byte_DS3231(SLAVE_ADDR_WR_DS3231);        //写入设备ID及写信号
 write_byte_DS3231(address);        //X地址
 write_byte_DS3231(thedata);        //写入设备ID及读信
 stop_DS3231();
 }
 
 void DS3231_Init()
 {
 Single_Write(DS3231_CONTROL, 0x1C);
 Single_Write(DS3231_STATUS, 0x00);
 }
 void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec)
 {
 uchar temp=0;
 temp=HEX2BCD(yea);
 Single_Write(DS3231_YEAR,temp);   //修改年
 
 temp=HEX2BCD(mon);
 Single_Write(DS3231_MONTH,temp);  //修改月
 
 temp=HEX2BCD(da);
 Single_Write(DS3231_DAY,temp);    //修改日
 
 temp=HEX2BCD(hou);
 Single_Write(DS3231_HOUR,temp);   //修改时
 
 temp=HEX2BCD(min);
 Single_Write(DS3231_MINUTE,temp); //修改分
 
 temp=HEX2BCD(sec);
 Single_Write(DS3231_SECOND,temp); //修改秒
 }
 
 void OLED_Init()
 {
 OLED_Port_Initial();
 OLED_Write_Comm(0xAE);
 OLED_Write_Comm(0x02);
 OLED_Write_Comm(0x10);
 OLED_Write_Comm(0x40);    /*set display start line*
 OLED_Write_Comm(0xB0);    /*set page address*/
 OLED_Write_Comm(0x81);    /*contract control*/
 OLED_Write_Comm(0x80);    /*128*/
 
 OLED_Write_Comm(0xA1);    /*set segment remap*/
 OLED_Write_Comm(0xA4);    /*normal display*/
 OLED_Write_Comm(0xA6);    /*normal / reverse*/
 
 OLED_Write_Comm(0xA8);    /*multiplex ratio*/
 OLED_Write_Comm(0x1F);    /*duty = 1/32*/
 OLED_Write_Comm(0xC8);    /*Com scan direction*/
 OLED_Write_Comm(0xD3);    /*set display offset*/
 OLED_Write_Comm(0x00);
 
 OLED_Write_Comm(0xD5);    /*set osc division*/
 OLED_Write_Comm(0x00);
 
 OLED_Write_Comm(0xD8);    /*set area color mode off*/
 OLED_Write_Comm(0x00);
 
 OLED_Write_Comm(0xD9);    /*set pre-charge period*/
 OLED_Write_Comm(0x01);
 
 OLED_Write_Comm(0xDA);    /*set COM pins*/
 OLED_Write_Comm(0x12);
 OLED_Write_Comm(0xAF);    /*display ON*/
 
 }
 void OLED_Port_Initial(void)
 {       OLED_RES_LOW;
 OLED_CS_OFF;
 OLED_DC_COMM;
 OLED_SCLK_HIGH;
 OLED_SDIN_HIGH;
 Delay_Ms(200);
 OLED_RES_HIGH;
 Delay_Ms(200);
 }
 //向写OLED模块写命令函数:把命令写入OLED命令寄存器,高位在前
 void OLED_Write_Comm(uchar comm)
 {
 uchar i;
 OLED_DC_COMM;                                                //命令模式
 OLED_CS_ON;                                                        //开启片选
 for(i=0;i<8;i++)
 {
 OLED_SCLK_LOW;                        //制造SCLK上升沿
 if(0x80==(comm&0x80))                                //把最高位状态赋给SDIN
 OLED_SDIN_HIGH;
 else
 OLED_SDIN_LOW;
 OLED_SCLK_HIGH;
 comm<<=1;                                                //命令向左移一位
 }
 OLED_CS_OFF;                                //关闭片选
 }
 void OLED_Write_Data(uchar data)
 {
 uchar i;
 OLED_DC_DATA;                                //数据模式
 OLED_CS_ON;                                //开启片选
 for(i=0;i<8;i++)
 {
 OLED_SCLK_LOW;                        //制造SCLK上升沿
 if(0x80==(data&0x80))                        //把最高位状态赋给SDIN
 OLED_SDIN_HIGH;
 else
 OLED_SDIN_LOW;
 OLED_SCLK_HIGH;
 data<<=1;                                                //命令向左移一位
 }
 OLED_CS_OFF;                                //关闭片选
 }
 //开启OLED显示
 void OLED_Display_On(void)
 {
 OLED_Write_Comm(0X8D);  //SET DCDC命令
 OLED_Write_Comm(0X14);  //DCDC ON
 OLED_Write_Comm(0XAF);  //DISPLAY ON
 }
 void OLED_Display_Off(void)
 {
 OLED_Write_Comm(0X8D);  //SET DCDC命令
 OLED_Write_Comm(0X10);  //DCDC OFF
 OLED_Write_Comm(0XAE);  //DISPLAY OFF
 //OLED_SDIN_HIGH;
 }
 //清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
 void OLED_Clear(void)
 {
 uchar i,n;
 for(i=0;i<4;i++)
 {
 OLED_Write_Comm(0xb0+i);    //设置页地址(0~7)
 OLED_Write_Comm(0x00);      //设置显示位置—列低地址
 OLED_Write_Comm(0x10);      //设置显示位置—列高地址
 for(n=0;n<132;n++)
 OLED_Write_Data(0x00);
 }
 }
 //满屏函数,屏幕全亮
 void OLED_Full(void)
 {
 uchar i,n;
 for(i=0;i<4;i++)
 {
 OLED_Write_Comm(0xb0+i);    //设置页地址(0~7)
 OLED_Write_Comm(0x00);      //设置显示位置—列低地址
 OLED_Write_Comm(0x10);      //设置显示位置—列高地址
 for(n=0;n<128;n++)
 OLED_Write_Data(0xff);
 }
 }
 void OLED_ShowChar(uchar startpage,uchar startcolumn,const uchar *dis_code,uchar len ,uchar width,uchar mode)
 {
 uchar x_temp = 0;
 uchar y_temp = 0;
 uchar page_sum= 0;
 uint i_temp =0;
 uchar col_l = 0;
 uchar col_h = 0;
 col_l=LO_UINT8(startcolumn);
 col_h=HI_UINT8(startcolumn);
 if(width<=8)
 {
 page_sum =1;
 }
 else if((width>8) && (width<=16))
 {
 page_sum =2;
 }
 else if((width>16) && (width<=24))
 {
 page_sum =3;
 }
 else if((width>24) && (width<=32))
 {
 page_sum =4;
 }
 else
 {
 return;
 }
 for(y_temp=startpage;y_temp<page_sum+startpage;y_temp++)
 {
 OLED_Write_Comm(col_l+0x00);      /*set lower column address*/
 OLED_Write_Comm(col_h+0x10);      /*set higher column address*/
 if(y_temp <4)
 OLED_Write_Comm(0xB0+y_temp);    /*set page address*/
 else//防止溢出
 OLED_Write_Comm(0xB0+y_temp-4);
 for(x_temp = startcolumn; x_temp<(len+startcolumn); x_temp++)
 {
 if(1==mode)
 OLED_Write_Data(dis_code[i_temp++]);
 else
 OLED_Write_Data(~(dis_code[i_temp++]));
 }
 }
 }
 
 void LCD_Set_Pos(byte x, byte y)
 {
 OLED_Write_Comm(0xb0+y);
 OLED_Write_Comm(((x&0xf0)>>4)|0x10);
 OLED_Write_Comm((x&0x0f)|0x01);
 }
 
 //==============================================================
 //功能描述:写入一组标准ASCII字符
 //参数:显示的位置(x,y),y为页范围0~7,要显示的字符串
 //返回:无
 //==============================================================
 void write_6_8_char(byte x,byte y,byte ucData)
 {
 byte i, ucDataTmp;
 ucDataTmp = ucData-32;
 if(x > 126)
 {
 x= 0;
 y++;
 }
 
 LCD_Set_Pos(x, y);
 
 for(i = 0; i < 6; i++)
 {
 OLED_Write_Data(F6x8[ucDataTmp][i]);
 }
 }
 
 void write_6_8_string(byte x,byte y,byte ch[])
 {
 byte c=0,i=0,j=0;
 while (ch[j]!='\0')
 {
 c =ch[j]-32;
 if(x>126){x=0;y++;}
 LCD_Set_Pos(x,y);
 for(i=0;i<6;i++)
 OLED_Write_Data(F6x8[c][i]);
 x+=6;
 j++;
 }
 }
 void write_6_8_number(unsigned char x,unsigned char y, float number)
 {
 unsigned char i=0;
 unsigned char temp[16];
 unsigned char *point=temp;
 float decimal;
 int data;
 
 if(number<0)
 {
 temp[0]='-';
 write_6_8_char(x,y,temp[0]);
 x+=6;
 number=-number;
 }
 
 data=(int)number;
 decimal=number-data;     //得到小数部
 if(data>=1000)           //是否可被1000整除
 {
 temp[i]=48+data/1000;
 data=data%1000;
 i++;
 }
 
 
 if(data>=100)              //是否可被100整除
 {
 temp[i]=48+data/100;
 data=data%100;
 i++;
 }
 else
 if(data<100&&i!=0)
 {
 temp[i]=0+48;
 i++;
 }
 
 if(data>=10)                  //是否可被10整除
 {
 temp[i]=48+data/10;
 data=data%10;
 i++;
 }
 else
 if(data<10&&i!=0)
 {
 temp[i]=48;
 i++;
 }
 
 temp[i]=48+data;
 
 
 if(decimal>=0.0001)           //判断是否为小数
 {
 i++;
 temp[i]='.';                //加小数点
 i++;
 
 data=(int)(decimal*1000);
 
 temp[i]=48+data/100;
 
 data=data%100;
 i++;
 
 if(data>0)
 {
 temp[i]=48+data/10;
 data=data%10;
 
 
 }
 if(data>=0)
 {
 i++;
 temp[i]=data+48;
 }
 
 }
 
 i++;
 temp[i]='\0';
 write_6_8_string(x,y,point);
 
 }
 
 //在指定的位置显示字符串,字符大小:16*8(字符)、16*16(汉字)
 void OLED_Show_String16(uchar startpage,uchar startcolumn,uchar *pdata,uchar mode)
 {
 uchar adata[3];
 uchar currentcolumn=startcolumn;
 while(*pdata)
 {
 adata[0]=*pdata;
 if(((*pdata) < 0x80) && ((*pdata) >= 0x20))                //ASCI码为字符
 {
 OLED_ShowChar(startpage,currentcolumn,(uchar *)&Ascii_8x16[(*pdata-0x20)][0],8,16,mode);
 currentcolumn+=8;
 }
 if(((*pdata) >= 0x80) && ((*pdata) <= 0xFE))        //如果为汉字
 {
 uchar tmp = 0;
 uchar i = 0;
 uchar readData;
 adata[1]= *(pdata + 1);
 while(1)
 {
 readData = (GB16[i].Index[0]);
 if(0 == readData)
 break;
 if(adata[0] == readData)
 {
 readData =(GB16[i].Index[1]);
 if(adata[1] == readData)
 {
 tmp = i;
 break;
 }
 }
 i++;
 }
 OLED_ShowChar(startpage,currentcolumn,(uchar *)&GB16[tmp].Msk[0],16,16,mode);
 currentcolumn+=16;
 pdata++;
 }
 pdata++;
 }
 }
 unsigned int year=2015,month=11,date=16,week=1,hour=13,min=48,second=20;
 void main(void)//主函数
 {
 //uint Din=0;
 uchar i=0;
 Init_IO();//初始化IO口
 /*------选择系统主时钟为8MHz-------*/
 BCSCTL1 &= ~XT2OFF;                 //打开XT2高频晶体振荡器
 do
 {
 IFG1 &= ~OFIFG;                 //清除晶振失败标志
 for (i = 0xFF; i > 0; i--);     //等待8MHz晶体起振
 }
 while ((IFG1 & OFIFG));             //晶振失效标志仍然存在?
 BCSCTL2 |= SELM_2 + SELS;           //MCLK和SMCLK选择高频晶振
 OLED_Init();                                //OLED模块初始化
 OLED_Clear();
 OLED_Display_On();
 DS3231_Init();//初始化
 ModifyTime(15,11,16,16,48,01);//初始化时钟,2015/11/16,16/48/01
 while(1)//无限循环
 {
 Tempreture=MLX90614_Read(0x07);//读地址7的温度数据即物体温度
 Tempreture=Tempreture*0.02-273.15; // 温度换算
 
 year=BCD2HEX(Read_DS3231(DS3231_YEAR));//年
 month=BCD2HEX(Read_DS3231(DS3231_MONTH));//月
 date=BCD2HEX(Read_DS3231(DS3231_DAY));//日
 hour=BCD2HEX(Read_DS3231(DS3231_HOUR));//时
 
 min=BCD2HEX(Read_DS3231(DS3231_MINUTE));//分
 second=BCD2HEX(Read_DS3231(DS3231_SECOND));//秒
 week=BCD2HEX(Read_DS3231(DS3231_WEEK));//星期
 
 write_6_8_string(10,0,"temp:");
 write_6_8_number(65,0,Tempreture);
 
 write_6_8_string(10,1,"year");
 write_6_8_string(50,1,"mon");
 write_6_8_string(85,1,"day");
 
 write_6_8_number(10,2,2015);
 write_6_8_number(50,2,11);
 write_6_8_number(85,2,16);
 
 write_6_8_string(0,3,"wk");
 write_6_8_number(30,3,1);
 
 //write_6_8_string(35,4,"hour");
 write_6_8_number(75,3,22);
 
 //write_6_8_string(10,5,"min");
 write_6_8_number(90,3,10);
 
 //write_6_8_string(10,6,"second");
 // write_6_8_number(100,3,second);
 
 Delay_Ms(100);
 }
 }
 
 | 
 |