版主: wanchong , wangyu , eepwwp , firedom |
中科院
![]()
最后登陆时间:2014-08-02 23:02:45 |
上周日,我在成都市电子市场转了一天,几乎没有找到一家有我想要的GPS芯片--------不过,现在已经把GPS调节好了,数据精度u,也是提高了一个档次,就是采集还有问题,会出现一些时断时续~~~接下来,就要自己去做电池了,希望可以减轻重量。。至于数据传输模块,还是需要自己解决,还有显示模块,是不是也要去找整个全双拼场
|
中科院
![]()
最后登陆时间:2014-08-02 23:02:45 |
在gps芯片选择上,我使用了ublox的常见芯片,它的主要功能的实现就是刚开始的GPS定位原理,接收到发来的信号,它有一个基本的格式,是美国电子海洋协会制造的,LTE附一下对这个规则的解析格式的代码
unsigned char i = 0; while(Serial.available() > 0) { Uart_Buffer = Serial.read(); //获取GPS信息 Serial.write(Uart_Buffer); //测试使用 if(Uart_Buffer == '$') { RX_Count = 0; //Flag_GPS_OK = 0; } if(RX_Count < 6) { GPS_COM[RX_Count++] = Uart_Buffer; } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'G'&& GPS_COM[4] == 'G'&& GPS_COM[5] == 'A' ) //获取GPGGA数据 { RX_GPGGA_Buffer[RX_Count] = Uart_Buffer; if(RX_GPGGA_Buffer[RX_Count] == '\n') { Flag_GPGGA_OK = 1; } else { RX_Count++; } } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'R'&& GPS_COM[4] == 'M'&& GPS_COM[5] == 'C' ) //获取GPRMC数据 { RX_GPRMC_Buffer[RX_Count] = Uart_Buffer; if(RX_GPRMC_Buffer[RX_Count] == '\n') { Flag_GPRMC_OK = 1; } else { RX_Count++; } } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'G'&& GPS_COM[4] == 'L'&& GPS_COM[5] == 'L' ) //获取GPGLL数据 { if(Uart_Buffer == '\n') { Flag_GPS_OK = 1; //一组数据都是最后一帧是GPGLL,接收完GPGLL说明接收数据完成 } } } if(Flag_GPS_OK == 1) { Flag_GPS_OK = 0; Serial.print("**************************************************\n"); if(Flag_GPGGA_OK == 1) { Serial.print("UTC_Time:"); Flag_GPGGA_OK = 0; UTC_Hour = (RX_GPGGA_Buffer[7]-0x30)*10+(RX_GPGGA_Buffer[8]-0x30); //获取UTC时间 UTC_Min = (RX_GPGGA_Buffer[9]-0x30)*10+(RX_GPGGA_Buffer[10]-0x30); UTC_Sec = (RX_GPGGA_Buffer[11]-0x30)*10+(RX_GPGGA_Buffer[12]-0x30); Serial.print(UTC_Hour); Serial.print(':'); Serial.print(UTC_Min); Serial.print(':'); Serial.print(UTC_Sec); Serial.print("\n"); Serial.print("Altitude: "); //海拔 for(i = 0 ; i < 4 ; i++) { Altitude[i]=RX_GPGGA_Buffer[54+i]; Serial.print(Altitude[i]); } Serial.print(" m"); Serial.print("\n"); } if(Flag_GPRMC_OK == 1) { Serial.print("UTC_Date:"); Flag_GPRMC_OK = 0; UTC_Year = (RX_GPRMC_Buffer[57]-0x30)*10+(RX_GPRMC_Buffer[58]-0x30); //获取UTC日期 UTC_Month = (RX_GPRMC_Buffer[55]-0x30)*10+(RX_GPRMC_Buffer[56]-0x30); UTC_Day = (RX_GPRMC_Buffer[53]-0x30)*10+(RX_GPRMC_Buffer[54]-0x30); Serial.print("20"); Serial.print(UTC_Year); Serial.print('-'); Serial.print(UTC_Month); Serial.print('-'); Serial.print(UTC_Day); Serial.print("\n"); Serial.print("Latitude: "); Latitude_N_or_S = RX_GPRMC_Buffer[30]; //纬度 Serial.print(Latitude_N_or_S); Serial.print(" "); for(i = 0;i<10;i++) { Latitude[i]=RX_GPRMC_Buffer[19+i]; Serial.print(Latitude[i]); } Serial.print("\n"); Serial.print("Longitude: "); Longitude_E_or_W = RX_GPRMC_Buffer[44]; //经度 Serial.print(Longitude_E_or_W); Serial.print(" "); for(i = 0;i<11;i++) { Longitude[i]=RX_GPRMC_Buffer[32+i]; Serial.print(Longitude[i]); } Serial.print("\n"); Serial.print("Speed: "); //速度 for(i=0;i<5;i++) { Speed[i]=RX_GPRMC_Buffer[46+i]; Serial.print(Speed[i]); } Serial.print(" m/s"); Serial.print("\n"); } Uart_Buffer是指的接收到的没有最后一步解析的GPS信号。GPS_COM[6]; //存放当前GPS指令名称,例如:$GPGGA,这里的信号,可能会有干扰,如果不是规则里的信号,就直接忽略,然后接着下一步。 在gps芯片选择上,我使用了ublox的常见芯片,它的主要功能的实现就是刚开始的GPS定位原理,接收到发来的信号,它有一个基本的格式,是美国电子海洋协会制造的,LTE附一下对这个规则的解析格式的代码 unsigned char i = 0; while(Serial.available() > 0) { Uart_Buffer = Serial.read(); //获取GPS信息 Serial.write(Uart_Buffer); //测试使用 if(Uart_Buffer == '$') { RX_Count = 0; //Flag_GPS_OK = 0; } if(RX_Count < 6) { GPS_COM[RX_Count++] = Uart_Buffer; } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'G'&& GPS_COM[4] == 'G'&& GPS_COM[5] == 'A' ) //获取GPGGA数据 { RX_GPGGA_Buffer[RX_Count] = Uart_Buffer; if(RX_GPGGA_Buffer[RX_Count] == '\n') { Flag_GPGGA_OK = 1; } else { RX_Count++; } } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'R'&& GPS_COM[4] == 'M'&& GPS_COM[5] == 'C' ) //获取GPRMC数据 { RX_GPRMC_Buffer[RX_Count] = Uart_Buffer; if(RX_GPRMC_Buffer[RX_Count] == '\n') { Flag_GPRMC_OK = 1; } else { RX_Count++; } } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'G'&& GPS_COM[4] == 'L'&& GPS_COM[5] == 'L' ) //获取GPGLL数据 { if(Uart_Buffer == '\n') { Flag_GPS_OK = 1; //一组数据都是最后一帧是GPGLL,接收完GPGLL说明接收数据完成 } } } if(Flag_GPS_OK == 1) { Flag_GPS_OK = 0; Serial.print("**************************************************\n"); if(Flag_GPGGA_OK == 1) { Serial.print("UTC_Time:"); Flag_GPGGA_OK = 0; UTC_Hour = (RX_GPGGA_Buffer[7]-0x30)*10+(RX_GPGGA_Buffer[8]-0x30); //获取UTC时间 UTC_Min = (RX_GPGGA_Buffer[9]-0x30)*10+(RX_GPGGA_Buffer[10]-0x30); UTC_Sec = (RX_GPGGA_Buffer[11]-0x30)*10+(RX_GPGGA_Buffer[12]-0x30); Serial.print(UTC_Hour); Serial.print(':'); Serial.print(UTC_Min); Serial.print(':'); Serial.print(UTC_Sec); Serial.print("\n"); Serial.print("Altitude: "); //海拔 for(i = 0 ; i < 4 ; i++) { Altitude[i]=RX_GPGGA_Buffer[54+i]; Serial.print(Altitude[i]); } Serial.print(" m"); Serial.print("\n"); } if(Flag_GPRMC_OK == 1) { Serial.print("UTC_Date:"); Flag_GPRMC_OK = 0; UTC_Year = (RX_GPRMC_Buffer[57]-0x30)*10+(RX_GPRMC_Buffer[58]-0x30); //获取UTC日期 UTC_Month = (RX_GPRMC_Buffer[55]-0x30)*10+(RX_GPRMC_Buffer[56]-0x30); UTC_Day = (RX_GPRMC_Buffer[53]-0x30)*10+(RX_GPRMC_Buffer[54]-0x30); Serial.print("20"); Serial.print(UTC_Year); Serial.print('-'); Serial.print(UTC_Month); Serial.print('-'); Serial.print(UTC_Day); Serial.print("\n"); Serial.print("Latitude: "); Latitude_N_or_S = RX_GPRMC_Buffer[30]; //纬度 Serial.print(Latitude_N_or_S); Serial.print(" "); for(i = 0;i<10;i++) { Latitude[i]=RX_GPRMC_Buffer[19+i]; Serial.print(Latitude[i]); } Serial.print("\n"); Serial.print("Longitude: "); Longitude_E_or_W = RX_GPRMC_Buffer[44]; //经度 Serial.print(Longitude_E_or_W); Serial.print(" "); for(i = 0;i<11;i++) { Longitude[i]=RX_GPRMC_Buffer[32+i]; Serial.print(Longitude[i]); } Serial.print("\n"); Serial.print("Speed: "); //速度 for(i=0;i<5;i++) { Speed[i]=RX_GPRMC_Buffer[46+i]; Serial.print(Speed[i]); } Serial.print(" m/s"); Serial.print("\n"); } Uart_Buffer是指的接收到的没有最后一步解析的GPS信号。GPS_COM[6]; //存放当前GPS指令名称,例如:$GPGGA,这里的信号,可能会有干扰,如果不是规则里的信号,就直接忽略,然后接着下一步。 让12864写出要显示的数据 #include "LCD12864.h" //******************************************************************** //LCD12864 忙 信号检测 //******************************************************************** void LCD12864_WaitIdle() { unsigned char i; LCD12864_DA_PORT = 0xff; LCD12864_RS_PORT = 0; LCD12864_RW_PORT = 1; LCD12864_E_PORT = 1; while((LCD12864_DA_PORT&0x80)==1); /*等待BF 不为1*/ LCD12864_E_PORT = 0; for(i=0;i<5;i++); } //******************************************************************** //检测忙信号写入命令字 com_da 为待写入的命令字 //******************************************************************** void LCD12864_COM_Write( unsigned char com_da) { LCD12864_WaitIdle(); LCD12864_RS_PORT = 0; LCD12864_RW_PORT = 0; LCD12864_DA_PORT = com_da; LCD12864_E_PORT = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); LCD12864_E_PORT = 0; } //******************************************************************** //不检测忙信号写入命令字 com_da 为待写入的命令字 //******************************************************************** void LCD12864_NoWaitIdle_COM_Write(unsigned char com_da) { LCD12864_RS_PORT = 0; LCD12864_RW_PORT = 0; LCD12864_DA_PORT = com_da; LCD12864_E_PORT = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); LCD12864_E_PORT = 0; } //******************************************************************** //数据写入 da 为待写入的8位数据 //******************************************************************** void LCD12864_Data_Write(unsigned char da) { LCD12864_WaitIdle(); /*检测忙信号*/ LCD12864_RS_PORT = 1; LCD12864_RW_PORT = 0; LCD12864_DA_PORT = da; LCD12864_E_PORT = 1; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); LCD12864_E_PORT = 0; } //************************************************************************************* //写连续字符函数 //************************************************************************************* void LCD12864_write_word(unsigned char *s) { while(*s>0) { LCD12864_Data_Write(*s); s++; } } //******************************************************************** //1MS为单位的延时程序,不准确 //******************************************************************** void lcd_delay_ms(unsigned char x) { unsigned char j; while(x--){ for(j=0;j<125;j++) {;} } } //******************************************************************** //LCD12864初始化 //******************************************************************** void LCD12864_Reset() { lcd_delay_ms(100); /*适当延时待LCD自动复位完成*/ LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/ lcd_delay_ms(10); LCD12864_NoWaitIdle_COM_Write(0x30); /*使用8位并口通讯*/ lcd_delay_ms(10); LCD12864_NoWaitIdle_COM_Write(0x0c); /*显示开及光标设置*/ lcd_delay_ms(10); LCD12864_NoWaitIdle_COM_Write(0x01); /*显示清屏*/ lcd_delay_ms(30); LCD12864_NoWaitIdle_COM_Write(0x06); /*DDRAM的地址计数器(AC)加1*/ lcd_delay_ms(30); } //void LCD12864_PHOTO_SET() //{ // LCD12864_COM_Write(0x36); // lcd_delay_ms(10); // LCD12864_COM_Write(0x36); // lcd_delay_ms(10); //} // void LCD12864_HAIZI_SET() { LCD12864_COM_Write(0x30); lcd_delay_ms(10); LCD12864_COM_Write(0x30); lcd_delay_ms(10); } // // //void LCD12864_HAIZI_WRITE(unsigned char xpos,unsigned char ypos,unsigned char daH,unsigned char daL) ////ST7920 汉字字符写入 ////参数说明: xpos 待写入的X位置 ////ypos 待写入的Y位置 ////daH 待写入的汉字的高八位 daL待写入的汉字的低八位 //{ // unsigned char xy_pos; // if((xpos>=8)||(ypos>=4) ) return; /*X位置超出显示范围退出*/ // if(ypos==0) xy_pos = 0x80 + xpos; // else if(ypos==1) xy_pos = 0x90 + xpos; /*计算转换地址*/ // else if(ypos==2) xy_pos = 0x88 + xpos; // else if(ypos==3) xy_pos = 0x98 + xpos; // LCD12864_COM_Write(xy_pos); /*写地址*/ // lcd_delay_ms(1); // LCD12864_Data_Write(daH); /*写高八位数据*/ // lcd_delay_ms(1); // LCD12864_Data_Write(daL); /*写低八位数据*/ // lcd_delay_ms(1); //} // // //void LCD12864_PHOTO_WRITE(unsigned char *img) //{ // unsigned char x,y,i,j; // unsigned int k=0; // y=0x80; /*设置起始 绘图区的 Y地址坐标*/ // x=0x80; /*设置起始 绘图区的 X地址坐标*/ // for(i=0;i<32;i++){ /*写上半部*/ // LCD12864_COM_Write(y); // LCD12864_COM_Write(x); // for(j=0;j<16;j++){ // LCD12864_Data_Write(img[k]); // k++; // } // y++; // } // // y=0x80; /*设置起始 绘图区的 Y地址坐标*/ // x=0x88; /*设置起始 绘图区的 X地址坐标*/ // for(i=0;i<32;i++){ /*写下半部*/ // LCD12864_COM_Write(y); // LCD12864_COM_Write(x); // for(j=0;j<16;j++){ // LCD12864_Data_Write(img[k]); // k++; // } // y++; // } // //} 这个程序的基本吗,大家都容易看懂,也就不多说。 LCD12864_Reset(); //初始化液晶 LCD12864_HAIZI_SET(); //设置为普通模式 Delay_ms(100); LCD12864_NoWaitIdle_COM_Write(0x80); //指针设置 LCD12864_write_word("※※※※※※※※"); LCD12864_NoWaitIdle_COM_Write(0x90); //指针设置 LCD12864_write_word(" 欢迎使用 "); LCD12864_NoWaitIdle_COM_Write(0x88); //指针设置 LCD12864_write_word("正在初始化GPS..."); LCD12864_NoWaitIdle_COM_Write(0x98); //指针设置 LCD12864_write_word("※※※※※※※※"); Uart_Init(); while(1) { Scan_Key(); if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'G' && RX_Buffer[6] == ',' && RX_Buffer[13] == '.') //确定是否收到"GPGGA"这一帧数据 { for( i = 0; i < 68 ; i++) { Display_GPGGA_Buffer[i] = RX_Buffer[i]; } Hour = (Display_GPGGA_Buffer[7]-0x30)*10+(Display_GPGGA_Buffer[8]-0x30)+8; //UTC时间转换到北京时间UTC+8 //0X30为ASCII码转换为数字 if( Hour >= 24) //溢出 { Hour %= 24; //获取当前Hour Flag_OV = 1; //日期进位 } else { Flag_OV = 0; } Min_High = Display_GPGGA_Buffer[9]; Min_Low = Display_GPGGA_Buffer[10]; Sec_High = Display_GPGGA_Buffer[11]; Sec_Low = Display_GPGGA_Buffer[12]; Flag_Calc_GPGGA_OK = 1; } if(Page == 0 && Flag_Calc_GPGGA_OK == 1) { LED1 = ~LED1; Flag_Calc_GPGGA_OK = 0; LCD12864_NoWaitIdle_COM_Write(0x80); //设置指针 LCD12864_write_word("★"); //显示内容 LCD12864_Data_Write(Hour/10+0x30); LCD12864_Data_Write(Hour%10+0x30); LCD12864_write_word("时"); LCD12864_Data_Write(Min_High); LCD12864_Data_Write(Min_Low); LCD12864_write_word("分"); LCD12864_Data_Write(Sec_High); LCD12864_Data_Write(Sec_Low); LCD12864_write_word("秒"); LCD12864_write_word("★"); LCD12864_NoWaitIdle_COM_Write(0x90); //设置指针 LCD12864_write_word("纬度:"); //显示内容 LCD12864_Data_Write(Display_GPGGA_Buffer[28]); //N 或者 S LCD12864_Data_Write(' '); LCD12864_Data_Write(Display_GPGGA_Buffer[17]); //纬度 LCD12864_Data_Write(Display_GPGGA_Buffer[18]); //纬度 LCD12864_write_word("°"); LCD12864_Data_Write(Display_GPGGA_Buffer[19]); //纬度 LCD12864_Data_Write(Display_GPGGA_Buffer[20]); //纬度 LCD12864_write_word("' "); LCD12864_NoWaitIdle_COM_Write(0x88); //设置指针 LCD12864_write_word("经度:"); //显示内容 LCD12864_Data_Write(Display_GPGGA_Buffer[42]); //E 或者 W LCD12864_Data_Write(Display_GPGGA_Buffer[30]); //经度 LCD12864_Data_Write(Display_GPGGA_Buffer[31]); LCD12864_Data_Write(Display_GPGGA_Buffer[32]); LCD12864_write_word("°"); LCD12864_Data_Write(Display_GPGGA_Buffer[33]); LCD12864_Data_Write(Display_GPGGA_Buffer[34]); LCD12864_write_word("' "); LCD12864_NoWaitIdle_COM_Write(0x98); //设置指针 LCD12864_write_word("海拔: "); //显示内容 LCD12864_Data_Write(Display_GPGGA_Buffer[54]); LCD12864_Data_Write(Display_GPGGA_Buffer[55]); LCD12864_Data_Write(Display_GPGGA_Buffer[56]); LCD12864_Data_Write(Display_GPGGA_Buffer[57]); LCD12864_write_word("米"); } if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'M' && RX_Buffer[52] == ',' && RX_Buffer[59] == ',') //确定是否收到"GPRMC"这一帧数据 { for( i = 0; i < 68 ; i++) { Display_GPRMC_Buffer[i] = RX_Buffer[i]; } Year_High = Display_GPRMC_Buffer[57]; Year_Low = Display_GPRMC_Buffer[58]; Month_High = Display_GPRMC_Buffer[55]; Month_Low = Display_GPRMC_Buffer[56]; Day_High = Display_GPRMC_Buffer[53]; Day_Low = Display_GPRMC_Buffer[54]; if(Flag_OV == 1) //有进位 { UTCDate2LocalDate(); //UTC日期转换为北京时间 } Flag_Calc_GPRMC_OK = 1; } if(Page == 1 && Flag_Calc_GPRMC_OK == 1) { LED1 = ~LED1; Flag_Calc_GPRMC_OK = 0; LCD12864_NoWaitIdle_COM_Write(0x80); //设置指针 LCD12864_write_word("20"); LCD12864_Data_Write(Year_High); LCD12864_Data_Write(Year_Low); LCD12864_write_word("年"); LCD12864_Data_Write(Month_High); LCD12864_Data_Write(Month_Low); LCD12864_write_word("月"); LCD12864_Data_Write(Day_High); LCD12864_Data_Write(Day_Low); LCD12864_write_word("日"); LCD12864_NoWaitIdle_COM_Write(0x90); //设置指针 LCD12864_write_word("速度: "); //显示内容 LCD12864_Data_Write(' '); LCD12864_Data_Write(Display_GPRMC_Buffer[46]); LCD12864_Data_Write(Display_GPRMC_Buffer[47]); LCD12864_Data_Write(Display_GPRMC_Buffer[48]); LCD12864_Data_Write(Display_GPRMC_Buffer[49]); LCD12864_Data_Write(Display_GPRMC_Buffer[50]); LCD12864_write_word("米"); } } } //**************************************************** //UTC日期与当地日期转换 //**************************************************** void UTCDate2LocalDate(void) { Day = (Day_High - 0x30) * 10 + (Day_Low-0x30) + 1; //日 加一 Month = (Month_High - 0x30) * 10 + (Month_Low - 0x30); Year = 2000 + (Year_High - 0x30) * 10 + (Year_Low - 0x30); MaxDay = GetMaxDay(Month,Year); //获取当月 天数 最大值 if(Day > MaxDay) //溢出 { Day = 1; Month += 1; if(Month > 12) { Year+=1; } } Day_High = Day/10 + 0x30; //转换日期值为ASCII Day_Low = Day%10 + 0x30; Month_High = Month/10 + 0x30; //转换月份值为ASCII Month_Low = Month%10 + 0x30; Year_High = Year%100/10 + 0x30; //转换年份值为ASCII Year_Low = Year%10 + 0x30; } //**************************************************** //获取当月日期最大值 //**************************************************** unsigned char GetMaxDay(unsigned char Month_Value,unsigned int Year_Value) { unsigned char iDays; switch(Month_Value) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: { iDays = 31; } break; case 2: { //2月份比较特殊,需要根据是不是闰年来判断当月是28天还29天 iDays = IsLeapYear(Year_Value)?29:28; } break; case 4: case 6: case 9: case 11: { iDays = 30; } break; default : break; } return(iDays); } //**************************************************** //闰年检测 //**************************************************** bit IsLeapYear(unsigned int uiYear) { return (((uiYear%4)==0)&&((uiYear%100)!=0))||((uiYear%400)==0); } //**************************************************** //按键扫描程序 //**************************************************** void Scan_Key() { if( KEY4 == 0 ) //按键1扫描 { Delay_ms(10); //延时去抖 if( KEY4 == 0 ) { while(KEY4 == 0); //等待松手 KEY_NUM = 4; Page = ~Page; LCD12864_NoWaitIdle_COM_Write(0X01); //清屏 } } } //**************************************************** //MS延时函数(12M晶振下测试) //**************************************************** void Delay_ms(unsigned int n) { unsigned int i,j; for(i=0;i<n;i++) for(j=0;j<123;j++); } 接着,把12864的口按标准接到伽利略板子上,再去完成ZIGBEE的调试 由于上一次发货太多,结果损失头大,这次就只好这样。 |
中科院
![]()
最后登陆时间:2014-08-02 23:02:45 |
不知道为什么代码发不上了,还得继续发
|
中科院
![]()
最后登陆时间:2014-08-02 23:02:45 |
#include "GPS.h"
//**************************************************** //UTC日期与当地日期转换 //**************************************************** void GPS_UBLOX::UTCDate2LocalDate(void) { unsigned char MaxDay; Beijing_Day = UTC_Day + 1; //日 加一 MaxDay = GetMaxDay(Beijing_Month,Beijing_Year); //获取当月 天数 最大值 if(Beijing_Day > MaxDay) //溢出 { Beijing_Day = 1; Beijing_Month += 1; if(Beijing_Month > 12) { Beijing_Year+=1; } } } //**************************************************** //UTC时间与当地时间转换 //**************************************************** void GPS_UBLOX::UTCTime2LocalTime(void) { unsigned char MaxDay; Beijing_Min = UTC_Min; Beijing_Sec = UTC_Sec; Beijing_Hour = UTC_Hour + 8; Beijing_Year = UTC_Year + 2000; Beijing_Month = UTC_Month; Beijing_Day = UTC_Day; if(Beijing_Hour >= 24) { Beijing_Hour %= 24; UTCDate2LocalDate(); } } //**************************************************** //获取当月日期最大值 //**************************************************** unsigned char GPS_UBLOX::GetMaxDay(unsigned char Month_Value,unsigned int Year_Value) { unsigned char iDays; switch(Month_Value) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: { iDays = 31; } break; case 2: { //2月份比较特殊,需要根据是不是闰年来判断当月是28天还29天 iDays = IsLeapYear(Year_Value)?29:28; } break; case 4: case 6: case 9: case 11: { iDays = 30; } break; default : break; } return(iDays); } //**************************************************** //闰年检测 //**************************************************** bool GPS_UBLOX::IsLeapYear(unsigned int uiYear) { return (((uiYear%4)==0)&&((uiYear%100)!=0))||((uiYear%400)==0); } //******************************************************** //获取GPS信息 //******************************************************** void GPS_UBLOX::Get_GPS() { unsigned char i = 0; while(Serial.available() > 0) { Uart_Buffer = Serial.read(); //获取GPS信息 Serial.write(Uart_Buffer); //测试使用 if(Uart_Buffer == '$') { RX_Count = 0; //Flag_GPS_OK = 0; } if(RX_Count < 6) { GPS_COM[RX_Count++] = Uart_Buffer; } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'G'&& GPS_COM[4] == 'G'&& GPS_COM[5] == 'A' ) //获取GPGGA数据 { RX_GPGGA_Buffer[RX_Count] = Uart_Buffer; if(RX_GPGGA_Buffer[RX_Count] == '\n') { Flag_GPGGA_OK = 1; } else { RX_Count++; } } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'R'&& GPS_COM[4] == 'M'&& GPS_COM[5] == 'C' ) //获取GPRMC数据 { RX_GPRMC_Buffer[RX_Count] = Uart_Buffer; if(RX_GPRMC_Buffer[RX_Count] == '\n') { Flag_GPRMC_OK = 1; } else { RX_Count++; } } else if( GPS_COM[0] == '$' && GPS_COM[1] == 'G'&& GPS_COM[2] == 'P'&& GPS_COM[3] == 'G'&& GPS_COM[4] == 'L'&& GPS_COM[5] == 'L' ) //获取GPGLL数据 { if(Uart_Buffer == '\n') { Flag_GPS_OK = 1; //一组数据都是最后一帧是GPGLL,接收完GPGLL说明接收数据完成 } } } if(Flag_GPS_OK == 1) { Flag_GPS_OK = 0; Serial.print("**************************************************\n"); if(Flag_GPGGA_OK == 1) { Serial.print("UTC_Time:"); Flag_GPGGA_OK = 0; UTC_Hour = (RX_GPGGA_Buffer[7]-0x30)*10+(RX_GPGGA_Buffer[8]-0x30); //获取UTC时间 UTC_Min = (RX_GPGGA_Buffer[9]-0x30)*10+(RX_GPGGA_Buffer[10]-0x30); UTC_Sec = (RX_GPGGA_Buffer[11]-0x30)*10+(RX_GPGGA_Buffer[12]-0x30); Serial.print(UTC_Hour); Serial.print(':'); Serial.print(UTC_Min); Serial.print(':'); Serial.print(UTC_Sec); Serial.print("\n"); Serial.print("Altitude: "); //海拔 for(i = 0 ; i < 4 ; i++) { Altitude[i]=RX_GPGGA_Buffer[54+i]; Serial.print(Altitude[i]); } Serial.print(" m"); Serial.print("\n"); } if(Flag_GPRMC_OK == 1) { Serial.print("UTC_Date:"); Flag_GPRMC_OK = 0; UTC_Year = (RX_GPRMC_Buffer[57]-0x30)*10+(RX_GPRMC_Buffer[58]-0x30); //获取UTC日期 UTC_Month = (RX_GPRMC_Buffer[55]-0x30)*10+(RX_GPRMC_Buffer[56]-0x30); UTC_Day = (RX_GPRMC_Buffer[53]-0x30)*10+(RX_GPRMC_Buffer[54]-0x30); Serial.print("20"); Serial.print(UTC_Year); Serial.print('-'); Serial.print(UTC_Month); Serial.print('-'); Serial.print(UTC_Day); Serial.print("\n"); Serial.print("Latitude: "); Latitude_N_or_S = RX_GPRMC_Buffer[30]; //纬度 Serial.print(Latitude_N_or_S); Serial.print(" "); for(i = 0;i<10;i++) { Latitude[i]=RX_GPRMC_Buffer[19+i]; Serial.print(Latitude[i]); } Serial.print("\n"); Serial.print("Longitude: "); Longitude_E_or_W = RX_GPRMC_Buffer[44]; //经度 Serial.print(Longitude_E_or_W); Serial.print(" "); for(i = 0;i<11;i++) { Longitude[i]=RX_GPRMC_Buffer[32+i]; Serial.print(Longitude[i]); } Serial.print("\n"); Serial.print("Speed: "); //速度 for(i=0;i<5;i++) { Speed[i]=RX_GPRMC_Buffer[46+i]; Serial.print(Speed[i]); } Serial.print(" m/s"); Serial.print("\n"); } UTCTime2LocalTime(); Serial.print("Beijing_Time:"); Serial.print(Beijing_Hour); Serial.print(':'); Serial.print(Beijing_Min); Serial.print(':'); Serial.print(Beijing_Sec); Serial.print("\n"); Serial.print("Beijing_Date:"); Serial.print(Beijing_Year); Serial.print('-'); Serial.print(Beijing_Month); Serial.print('-'); Serial.print(Beijing_Day); Serial.print("\n"); Serial.print("**************************************************\n"); Serial.print("\n"); } } //******************************************************** //初始化GPS用到的变量 //******************************************************** void GPS_UBLOX::Init_GPS() { Flag_GPGGA_OK = 0; RX_Count = 0; Uart_Buffer = 0; } |
中科院
![]()
最后登陆时间:2014-08-02 23:02:45 |
#include "sim900a.h"
#include "usart.h" #include "delay.h" #include "led.h" #include "key.h" #include "lcd.h" #include "dma.h" #include "flash.h" #include "touch.h" #include "malloc.h" #include "string.h" #include "text.h" #include "usart2.h" #include "ff.h" //usmart支持部分 //将收到的AT指令应答数据返回给电脑串口 //mode:0,不清零USART2_RX_STA; // 1,清零USART2_RX_STA; void sim_at_response(u8 mode) { if(USART2_RX_STA&0X8000) //接收到一次数据了 { USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符 printf("%s",USART2_RX_BUF); //发送到串口 if(mode)USART2_RX_STA=0; } } /////////////////////////////////////////////////////////////////////////////////////////////////////////// //ATK-SIM900A 各项测试(拨号测试、短信测试、GPRS测试)共用代码 //sim900a发送命令后,检测接收到的应答 //str:期待的应答结果 //返回值:0,没有得到期待的应答结果 // 其他,期待应答结果的位置(str的位置) u8* sim900a_check_cmd(u8 *str) { char *strx=0; if(USART2_RX_STA&0X8000) //接收到一次数据了 { USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0;//添加结束符 strx=strstr((const char*)USART2_RX_BUF,(const char*)str); } return (u8*)strx; } //向sim900a发送命令 //cmd:发送的命令字符串(不需要添加回车了),当cmd<0XFF的时候,发送数字(比如发送0X1A),大于的时候发送字符串. //ack:期待的应答结果,如果为空,则表示不需要等待应答 //waittime:等待时间(单位:10ms) //返回值:0,发送成功(得到了期待的应答结果) // 1,发送失败 u8 sim900a_send_cmd(u8 *cmd,u8 *ack,u16 waittime) { u8 res=0; USART2_RX_STA=0; if((u32)cmd<=0XFF) { while(DMA1_Channel7->CNDTR!=0); //等待通道7传输完成 USART2->DR=(u32)cmd; }else u2_printf("%s\r\n",cmd);//发送命令 if(ack&&waittime) //需要等待应答 { while(--waittime) //等待倒计时 { delay_ms(10); if(USART2_RX_STA&0X8000)//接收到期待的应答结果 { if(sim900a_check_cmd(ack))break;//得到有效数据 USART2_RX_STA=0; } } if(waittime==0)res=1; } return res; } //将1个字符转换为16进制数字 //chr:字符,0~9/A~F/a~F //返回值:chr对应的16进制数值 u8 sim900a_chr2hex(u8 chr) { if(chr>='0'&&chr<='9')return chr-'0'; if(chr>='A'&&chr<='F')return (chr-'A'+10); if(chr>='a'&&chr<='f')return (chr-'a'+10); return 0; } //将1个16进制数字转换为字符 //hex:16进制数字,0~15; //返回值:字符 u8 sim900a_hex2chr(u8 hex) { if(hex<=9)return hex+'0'; if(hex>=10&&hex<=15)return (hex-10+'A'); return '0'; } //unicode gbk 转换函数 //src:输入字符串 //dst:输出(uni2gbk时为gbk内码,gbk2uni时,为unicode字符串) //mode:0,unicode到gbk转换; // 1,gbk到unicode转换; void sim900a_unigbk_exchange(u8 *src,u8 *dst,u8 mode) { u16 temp; u8 buf[2]; if(mode)//gbk 2 unicode { while(*src!=0) { if(*src<0X81) //非汉字 { temp=(u16)ff_convert((WCHAR)*src,1); src++; }else //汉字,占2个字节 { buf[1]=*src++; buf[0]=*src++; temp=(u16)ff_convert((WCHAR)*(u16*)buf,1); } *dst++=sim900a_hex2chr((temp>>12)&0X0F); *dst++=sim900a_hex2chr((temp>>8)&0X0F); *dst++=sim900a_hex2chr((temp>>4)&0X0F); *dst++=sim900a_hex2chr(temp&0X0F); } }else //unicode 2 gbk { while(*src!=0) { buf[1]=sim900a_chr2hex(*src++)*16; buf[1]+=sim900a_chr2hex(*src++); buf[0]=sim900a_chr2hex(*src++)*16; buf[0]+=sim900a_chr2hex(*src++); temp=(u16)ff_convert((WCHAR)*(u16*)buf,0); if(temp<0X80){*dst=temp;dst++;} else {*(u16*)dst=swap16(temp);dst+=2;} } } *dst=0;//添加结束符 } //键盘码表 const u8* kbd_tbl1[13]={"1","2","3","4","5","6","7","8","9","*","0","#","DEL"}; const u8* kbd_tbl2[13]={"1","2","3","4","5","6","7","8","9",".","0","#","DEL"}; u8** kbd_tbl; u8* kbd_fn_tbl[2]; //加载键盘界面(尺寸为240*140) //x,y:界面起始坐标(320*240分辨率的时候,x必须为0) void sim900a_load_keyboard(u16 x,u16 y,u8 **kbtbl) { u16 i; POINT_COLOR=RED; kbd_tbl=kbtbl; LCD_Fill(x,y,x+240,y+140,WHITE); LCD_DrawRectangle(x,y,x+240,y+140); LCD_DrawRectangle(x+80,y,x+160,y+140); LCD_DrawRectangle(x,y+28,x+240,y+56); LCD_DrawRectangle(x,y+84,x+240,y+112); POINT_COLOR=BLUE; for(i=0;i<15;i++) { if(i<13)Show_Str_Mid(x+(i%3)*80,y+6+28*(i/3),(u8*)kbd_tbl[i],16,80); else Show_Str_Mid(x+(i%3)*80,y+6+28*(i/3),kbd_fn_tbl[i-13],16,80); } } //按键状态设置 //x,y:键盘坐标 //key:键值(0~8) //sta:状态,0,松开;1,按下; void sim900a_key_staset(u16 x,u16 y,u8 keyx,u8 sta) { u16 i=keyx/3,j=keyx%3; if(keyx>15)return; if(sta)LCD_Fill(x+j*80+1,y+i*28+1,x+j*80+78,y+i*28+26,GREEN); else LCD_Fill(x+j*80+1,y+i*28+1,x+j*80+78,y+i*28+26,WHITE); if(j&&(i>3))Show_Str_Mid(x+j*80,y+6+28*i,(u8*)kbd_fn_tbl[keyx-13],16,80); else Show_Str_Mid(x+j*80,y+6+28*i,(u8*)kbd_tbl[keyx],16,80); } //得到触摸屏的输入 //x,y:键盘坐标 //返回值:按键键值(1~15有效;0,无效) u8 sim900a_get_keynum(u16 x,u16 y) { u16 i,j; static u8 key_x=0;//0,没有任何按键按下;1~15,1~15号按键按下 u8 key=0; tp_dev.scan(0); if(tp_dev.sta&TP_PRES_DOWN) //触摸屏被按下 { for(i=0;i<5;i++) { for(j=0;j<3;j++) { if(tp_dev.x<(x+j*80+80)&&tp_dev.x>(x+j*80)&&tp_dev.y<(y+i*28+28)&&tp_dev.y>(y+i*28)) { key=i*3+j+1; break; } } if(key) { if(key_x==key)key=0; else { sim900a_key_staset(x,y,key_x-1,0); key_x=key; sim900a_key_staset(x,y,key_x-1,1); } break; } } }else if(key_x) { sim900a_key_staset(x,y,key_x-1,0); key_x=0; } return key; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// //拨号测试部分代码 //sim900a拨号测试 //用于拨打电话和接听电话 //返回值:0,正常 // 其他,错误代码 u8 sim900a_call_test(void) { u8 key; u16 lenx; u8 callbuf[20]; u8 pohnenumlen=0; //号码长度,最大15个数 u8 *p,*p1,*p2; u8 oldmode=0; u8 cmode=0; //模式 //0:等待拨号 //1:拨号中 //2:通话中 //3:接收到来电 LCD_Clear(WHITE); if(sim900a_send_cmd("AT+CLIP=1","OK",200))return 1; //设置来电显示 if(sim900a_send_cmd("AT+COLP=1","OK",200))return 2; //设置被叫号码显示 p1=mymalloc(SRAMIN,20); //申请20直接用于存放号码 if(p1==NULL)return 2; POINT_COLOR=RED; Show_Str_Mid(0,30,"ATK-SIM900A 拨号测试",16,240); Show_Str(40,70,200,16,"请拨号:",16,0); kbd_fn_tbl[0]="拨号"; kbd_fn_tbl[1]="返回"; sim900a_load_keyboard(0,180,(u8**)kbd_tbl1); POINT_COLOR=BLUE; while(1) { delay_ms(10); if(USART2_RX_STA&0X8000) //接收到数据 { sim_at_response(0); if(cmode==1||cmode==2) { if(cmode==1)if(sim900a_check_cmd("+COLP:"))cmode=2; //拨号成功 if(sim900a_check_cmd("NO CARRIER"))cmode=0; //拨号失败 if(sim900a_check_cmd("NO ANSWER"))cmode=0; //拨号失败 if(sim900a_check_cmd("ERROR"))cmode=0; //拨号失败 } if(sim900a_check_cmd("+CLIP:"))//接收到来电 { cmode=3; p=sim900a_check_cmd("+CLIP:"); p+=8; p2=(u8*)strstr((const char *)p,"\""); p2[0]=0;//添加结束符 strcpy((char*)p1,(char*)p); } USART2_RX_STA=0; } key=sim900a_get_keynum(0,180); if(key) { if(key<13) { if(cmode==0&&pohnenumlen<15) { callbuf[pohnenumlen++]=kbd_tbl[key-1][0]; u2_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]); }else if(cmode==2)//通话中 { u2_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]); delay_ms(100); u2_printf("AT+VTS=%c\r\n",kbd_tbl[key-1][0]); LCD_ShowChar(40+56,90,kbd_tbl[key-1][0],16,0); } }else { if(key==13)if(pohnenumlen&&cmode==0)pohnenumlen--;//删除 if(key==14)//执行拨号 { if(cmode==0)//拨号模式 { callbuf[pohnenumlen]=0; //最后加入结束符 u2_printf("ATD%s;\r\n",callbuf);//拨号 delay_ms(10); //等待10ms cmode=1; //拨号中模式 }else { sim900a_send_cmd("ATH","OK",100);//挂机 sim900a_send_cmd("ATH","OK",100);//挂机 cmode=0; } } if(key==15) { if(cmode==3)//接收到来电 { sim900a_send_cmd("ATA","OK",200);//发送应答指令 Show_Str(40+56,70,200,16,callbuf,16,0); cmode=2; }else { sim900a_send_cmd("ATH",0,0);//不管有没有在通话,都结束通话 break;//退出循环 } } } if(cmode==0)//只有在等待拨号模式有效 { callbuf[pohnenumlen]=0; LCD_Fill(40+56,70,239,70+16,WHITE); Show_Str(40+56,70,200,16,callbuf,16,0); } } if(oldmode!=cmode)//模式变化了 { switch(cmode) { case 0: kbd_fn_tbl[0]="拨号"; kbd_fn_tbl[1]="返回"; POINT_COLOR=RED; Show_Str(40,70,200,16,"请拨号:",16,0); LCD_Fill(40+56,70,239,70+16,WHITE); if(pohnenumlen) { POINT_COLOR=BLUE; Show_Str(40+56,70,200,16,callbuf,16,0); } break; case 1: POINT_COLOR=RED; Show_Str(40,70,200,16,"拨号中:",16,0); pohnenumlen=0; case 2: POINT_COLOR=RED; if(cmode==2)Show_Str(40,70,200,16,"通话中:",16,0); kbd_fn_tbl[0]="挂断"; kbd_fn_tbl[1]="返回"; break; case 3: POINT_COLOR=RED; Show_Str(40,70,200,16,"有来电:",16,0); POINT_COLOR=BLUE; Show_Str(40+56,70,200,16,p1,16,0); kbd_fn_tbl[0]="挂断"; kbd_fn_tbl[1]="接听"; break; } if(cmode==2)Show_Str(40,90,200,16,"DTMF音:",16,0); //通话中,可以通过键盘输入DTMF音 else LCD_Fill(40,90,120,90+16,WHITE); sim900a_load_keyboard(0,180,(u8**)kbd_tbl1); //显示键盘 oldmode=cmode; } if((lenx%50)==0)LED0=!LED0; lenx++; } myfree(SRAMIN,p1); return 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// //短信测试部分代码 //SIM900A读短信测试 void sim900a_sms_read_test(void) { u8 *p,*p1,*p2; u8 timex=0; u8 msgindex[3]; u8 msglen=0; u8 msgmaxnum=0; //短信最大条数 u8 key=0; u8 smsreadsta=0; //是否在短信显示状态 p=mymalloc(SRAMIN,200);//申请200个字节的内存 LCD_Clear(WHITE); POINT_COLOR=RED; Show_Str_Mid(0,30,"ATK-SIM900A 读短信测试",16,240); Show_Str(30,50,200,16,"读取: 总信息:",16,0); kbd_fn_tbl[0]="读取"; kbd_fn_tbl[1]="返回"; sim900a_load_keyboard(0,180,(u8**)kbd_tbl1);//显示键盘 while(1) { key=sim900a_get_keynum(0,180); if(key) { if(smsreadsta) { LCD_Fill(30,75,239,179,WHITE);//清除显示的短信内容 smsreadsta=0; } if(key<10||key==11) { if(msglen<2) { msgindex[msglen++]=kbd_tbl[key-1][0]; u2_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]); } if(msglen==2) { key=(msgindex[0]-'0')*10+msgindex[1]-'0'; if(key>msgmaxnum) { msgindex[0]=msgmaxnum/10+'0'; msgindex[1]=msgmaxnum%10+'0'; } } }else { if(key==13)if(msglen)msglen--;//删除 if(key==14&&msglen)//执行读取短信 { LCD_Fill(30,75,239,179,WHITE);//清除之前的显示 sprintf((char*)p,"AT+CMGR=%s",msgindex); if(sim900a_send_cmd(p,"+CMGR:",200)==0)//读取短信 { POINT_COLOR=RED; Show_Str(30,75,200,12,"状态:",12,0); Show_Str(30+75,75,200,12,"来自:",12,0); Show_Str(30,90,200,12,"接收时间:",12,0); Show_Str(30,105,200,12,"内容:",12,0); POINT_COLOR=BLUE; if(strstr((const char*)(USART2_RX_BUF),"UNREAD")==0)Show_Str(30+30,75,200,12,"已读",12,0); else Show_Str(30+30,75,200,12,"未读",12,0); p1=(u8*)strstr((const char*)(USART2_RX_BUF),","); p2=(u8*)strstr((const char*)(p1+2),"\""); p2[0]=0;//加入结束符 sim900a_unigbk_exchange(p1+2,p,0); //将unicode字符转换为gbk码 Show_Str(30+75+30,75,200,12,p,12,0); //显示电话号码 p1=(u8*)strstr((const char*)(p2+1),"/"); p2=(u8*)strstr((const char*)(p1),"+"); p2[0]=0;//加入结束符 Show_Str(30+54,90,200,12,p1-2,12,0); //显示接收时间 p1=(u8*)strstr((const char*)(p2+1),"\r"); //寻找回车符 sim900a_unigbk_exchange(p1+2,p,0); //将unicode字符转换为gbk码 Show_Str(30+30,105,180,75,p,12,0); //显示短信内容 smsreadsta=1; //标记有显示短信内容 }else { Show_Str(30,75,200,12,"无短信内容!!!请检查!!",12,0); delay_ms(1000); LCD_Fill(30,75,239,75+12,WHITE);//清除显示 } USART2_RX_STA=0; } if(key==15)break; } msgindex[msglen]=0; LCD_Fill(30+40,50,86,50+16,WHITE); Show_Str(30+40,50,86,16,msgindex,16,0); } if(timex==0) //2.5秒左右更新一次 { if(sim900a_send_cmd("AT+CPMS?","+CPMS:",200)==0) //查询优选消息存储器 { p1=(u8*)strstr((const char*)(USART2_RX_BUF),","); p2=(u8*)strstr((const char*)(p1+1),","); p2[0]='/'; if(p2[3]==',')//小于64K SIM卡,最多存储几十条短信 { msgmaxnum=(p2[1]-'0')*10+p2[2]-'0'; //获取最大存储短信条数 p2[3]=0; }else //如果是64K SIM卡,则能存储100条以上的信息 { msgmaxnum=(p2[1]-'0')*100+(p2[2]-'0')*10+p2[3]-'0';//获取最大存储短信条数 p2[4]=0; } sprintf((char*)p,"%s",p1+1); Show_Str(30+17*8,50,200,16,p,16,0); USART2_RX_STA=0; } } if((timex%20)==0)LED0=!LED0;//200ms闪烁 timex++; delay_ms(10); if(USART2_RX_STA&0X8000)sim_at_response(1);//检查从GSM模块接收到的数据 } myfree(SRAMIN,p); } //测试短信发送内容(70个字[UCS2的时候,1个字符/数字都算1个字]) const u8* sim900a_test_msg="您好,这是一条测试短信,由ATK-SIM900A GSM模块发送,模块购买地址:http://eboard.taobao.com,谢谢支持!"; //SIM900A发短信测试 void sim900a_sms_send_test(void) { u8 *p,*p1,*p2; u8 phonebuf[20]; //号码缓存 u8 pohnenumlen=0; //号码长度,最大15个数 u8 timex=0; u8 key=0; u8 smssendsta=0; //短信发送状态,0,等待发送;1,发送失败;2,发送成功 p=mymalloc(SRAMIN,100); //申请100个字节的内存,用于存放电话号码的unicode字符串 p1=mymalloc(SRAMIN,300);//申请300个字节的内存,用于存放短信的unicode字符串 p2=mymalloc(SRAMIN,100);//申请100个字节的内存 存放:AT+CMGS=p1 LCD_Clear(WHITE); POINT_COLOR=RED; Show_Str_Mid(0,30,"ATK-SIM900A 发短信测试",16,240); Show_Str(30,50,200,16,"发送给:",16,0); Show_Str(30,70,200,16,"状态:",16,0); Show_Str(30,90,200,16,"内容:",16,0); POINT_COLOR=BLUE; Show_Str(30+40,70,170,90,"等待发送",16,0);//显示状态 Show_Str(30+40,90,170,90,(u8*)sim900a_test_msg,16,0);//显示短信内容 kbd_fn_tbl[0]="发送"; kbd_fn_tbl[1]="返回"; sim900a_load_keyboard(0,180,(u8**)kbd_tbl1);//显示键盘 while(1) { key=sim900a_get_keynum(0,180); if(key) { if(smssendsta) { smssendsta=0; Show_Str(30+40,70,170,90,"等待发送",16,0);//显示状态 } if(key<10||key==11) { if(pohnenumlen<15) { phonebuf[pohnenumlen++]=kbd_tbl[key-1][0]; u2_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]); } }else { if(key==13)if(pohnenumlen)pohnenumlen--;//删除 if(key==14&&pohnenumlen) //执行发送短信 { Show_Str(30+40,70,170,90,"正在发送",16,0); //显示正在发送 smssendsta=1; sim900a_unigbk_exchange(phonebuf,p,1); //将电话号码转换为unicode字符串 sim900a_unigbk_exchange((u8*)sim900a_test_msg,p1,1);//将短信内容转换为unicode字符串. sprintf((char*)p2,"AT+CMGS=\"%s\"",p); if(sim900a_send_cmd(p2,">",200)==0) //发送短信命令+电话号码 { u2_printf("%s",p1); //发送短信内容到GSM模块 if(sim900a_send_cmd((u8*)0X1A,"+CMGS:",1000)==0)smssendsta=2;//发送结束符,等待发送完成(最长等待10秒钟,因为短信长了的话,等待时间会长一些) } if(smssendsta==1)Show_Str(30+40,70,170,90,"发送失败",16,0); //显示状态 else Show_Str(30+40,70,170,90,"发送成功",16,0); //显示状态 USART2_RX_STA=0; } if(key==15)break; } phonebuf[pohnenumlen]=0; LCD_Fill(30+54,50,239,50+16,WHITE); Show_Str(30+54,50,156,16,phonebuf,16,0); } if((timex%20)==0)LED0=!LED0;//200ms闪烁 timex++; delay_ms(10); if(USART2_RX_STA&0X8000)sim_at_response(1);//检查从GSM模块接收到的数据 } myfree(SRAMIN,p); myfree(SRAMIN,p1); myfree(SRAMIN,p2); } //sms测试主界面 void sim900a_sms_ui(u16 x,u16 y) { LCD_Clear(WHITE); POINT_COLOR=RED; Show_Str_Mid(0,y,"ATK-SIM900A 短信测试",16,240); Show_Str(x,y+40,200,16,"请选择:",16,0); Show_Str(x,y+60,200,16,"KEY0:读短信测试",16,0); Show_Str(x,y+80,200,16,"KEY1:发短信测试",16,0); Show_Str(x,y+100,200,16,"WK_UP:返回上级菜单",16,0); } //sim900a短信测试 //用于读短信或者发短信 //返回值:0,正常 // 其他,错误代码 u8 sim900a_sms_test(void) { u8 key; u8 timex=0; if(sim900a_send_cmd("AT+CMGF=1","OK",200))return 1; //设置文本模式 if(sim900a_send_cmd("AT+CSCS=\"UCS2\"","OK",200))return 2; //设置TE字符集为UCS2 if(sim900a_send_cmd("AT+CSMP=17,0,2,25","OK",200))return 3; //设置短消息文本模式参数 sim900a_sms_ui(40,30); while(1) { key=KEY_Scan(); if(key==1) { sim900a_sms_read_test(); sim900a_sms_ui(40,30); timex=0; }else if(key==2) { sim900a_sms_send_test(); sim900a_sms_ui(40,30); timex=0; }else if(key==3)break; timex++; if(timex==20) { timex=0; LED0=!LED0; } delay_ms(10); sim_at_response(1); //检查GSM模块发送过来的数据,及时上传给电脑 } sim900a_send_cmd("AT+CSCS=\"GSM\"","OK",200); //设置默认的GSM 7位缺省字符集 return 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// //GPRS测试部分代码 const u8 *modetbl[2]={"TCP","UDP"};//连接模式 //tcp/udp测试 //带心跳功能,以维持连接 //mode:0:TCP测试;1,UDP测试) //ipaddr:ip地址 //port:端口 void sim900a_tcpudp_test(u8 mode,u8* ipaddr,u8* port) { u8 *p,*p1,*p2,*p3; u8 key; u16 timex=0; u8 count=0; const u8* cnttbl[3]={"正在连接","连接成功","连接关闭"}; u8 connectsta=0; //0,正在连接;1,连接成功;2,连接关闭; u8 hbeaterrcnt=0; //心跳错误计数器,连续5次心跳信号无应答,则重新连接 u8 oldsta=0XFF; p=mymalloc(SRAMIN,100); //申请100字节内存 p1=mymalloc(SRAMIN,100); //申请100字节内存 LCD_Clear(WHITE); POINT_COLOR=RED; if(mode)Show_Str_Mid(0,30,"ATK-SIM900A UDP连接测试",16,240); else Show_Str_Mid(0,30,"ATK-SIM900A TCP连接测试",16,240); Show_Str(30,50,200,16,"WK_UP:退出测试 KEY0:发送数据",12,0); sprintf((char*)p,"IP地址:%s 端口:%s",ipaddr,port); Show_Str(30,65,200,12,p,12,0); //显示IP地址和端口 Show_Str(30,80,200,12,"状态:",12,0); //连接状态 Show_Str(30,100,200,12,"发送数据:",12,0); //连接状态 Show_Str(30,115,200,12,"接收数据:",12,0); //端口固定为8086 POINT_COLOR=BLUE; USART2_RX_STA=0; sprintf((char*)p,"AT+CIPSTART=\"%s\",\"%s\",\"%s\"",modetbl[mode],ipaddr,port); if(sim900a_send_cmd(p,"OK",500))return; //发起连接 while(1) { key=KEY_Scan(); if(key==3)//退出测试 { sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",500); //关闭连接 sim900a_send_cmd("AT+CIPSHUT","SHUT OK",500); //关闭移动场景 break; }else if(key==1&(hbeaterrcnt==0)) //发送数据(心跳正常时发送) { Show_Str(30+30,80,200,12,"数据发送中...",12,0); //提示数据发送中 if(sim900a_send_cmd("AT+CIPSEND",">",500)==0) //发送数据 { printf("CIPSEND DATA:%s\r\n",p1); //发送数据打印到串口 u2_printf("%s\r\n",p1); delay_ms(10); if(sim900a_send_cmd((u8*)0X1A,"SEND OK",1000)==0)Show_Str(30+30,80,200,12,"数据发送成功!",12,0);//最长等待10s else Show_Str(30+30,80,200,12,"数据发送失败!",12,0); delay_ms(500); }else sim900a_send_cmd((u8*)0X1B,0,0); //ESC,取消发送 oldsta=0XFF; } if((timex%20)==0) { LED0=!LED0; count++; if(connectsta==2||hbeaterrcnt>8)//连接中断了,或者连续8次心跳没有正确发送成功,则重新连接 { sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",500); //关闭连接 sim900a_send_cmd("AT+CIPSHUT","SHUT OK",500); //关闭移动场景 sim900a_send_cmd(p,"OK",500); //尝试重新连接 connectsta=0; hbeaterrcnt=0; } sprintf((char*)p1,"ATK-SIM900A %s测试 %d ",modetbl[mode],count); Show_Str(30+54,100,200,12,p1,12,0); } if(connectsta==0&&(timex%200)==0)//连接还没建立的时候,每2秒查询一次CIPSTATUS. { sim900a_send_cmd("AT+CIPSTATUS","OK",500); //查询连接状态 if(strstr((const char*)USART2_RX_BUF,"CLOSED"))connectsta=2; if(strstr((const char*)USART2_RX_BUF,"CONNECT OK"))connectsta=1; } if(connectsta==1&&timex>=600)//连接正常的时候,每6秒发送一次心跳 { timex=0; if(sim900a_send_cmd("AT+CIPSEND",">",200)==0)//发送数据 { sim900a_send_cmd((u8*)0X00,0,0); //发送数据:0X00 delay_ms(20); //必须加延时 sim900a_send_cmd((u8*)0X1A,0,0); //CTRL+Z,结束数据发送,启动一次传输 }else sim900a_send_cmd((u8*)0X1B,0,0); //ESC,取消发送 hbeaterrcnt++; printf("hbeaterrcnt:%d\r\n",hbeaterrcnt);//方便调试代码 } delay_ms(10); if(USART2_RX_STA&0X8000) //接收到一次数据了 { USART2_RX_BUF[USART2_RX_STA&0X7FFF]=0; //添加结束符 printf("%s",USART2_RX_BUF); //发送到串口 if(hbeaterrcnt) //需要检测心跳应答 { if(strstr((const char*)USART2_RX_BUF,"SEND OK"))hbeaterrcnt=0;//心跳正常 } p2=(u8*)strstr((const char*)USART2_RX_BUF,"+IPD"); if(p2)//接收到TCP/UDP数据 { p3=(u8*)strstr((const char*)p2,","); p2=(u8*)strstr((const char*)p2,":"); p2[0]=0;//加入结束符 sprintf((char*)p1,"收到%s字节,内容如下",p3+1);//接收到的字节数 LCD_Fill(30+54,115,239,130,WHITE); POINT_COLOR=BRED; Show_Str(30+54,115,156,12,p1,12,0); //显示接收到的数据长度 POINT_COLOR=BLUE; LCD_Fill(30,130,210,319,WHITE); Show_Str(30,130,180,190,p2+1,12,0); //显示接收到的数据 } USART2_RX_STA=0; } if(oldsta!=connectsta) { oldsta=connectsta; LCD_Fill(30+30,80,239,80+12,WHITE); Show_Str(30+30,80,200,12,(u8*)cnttbl[connectsta],12,0); //更新状态 } timex++; } myfree(SRAMIN,p); myfree(SRAMIN,p1); } //gprs测试主界面 void sim900a_gprs_ui(void) { LCD_Clear(WHITE); POINT_COLOR=RED; Show_Str_Mid(0,30,"ATK-SIM900A GPRS通信测试",16,240); Show_Str(30,50,200,16,"WK_UP:连接方式切换",16,0); Show_Str(30,90,200,16,"连接方式:",16,0); //连接方式通过WK_UP设置(TCP/UDP) Show_Str(30,110,200,16,"IP地址:",16,0); //IP地址可以键盘设置 Show_Str(30,130,200,16,"端口:",16,0); //端口固定为8086 kbd_fn_tbl[0]="连接"; kbd_fn_tbl[1]="返回"; sim900a_load_keyboard(0,180,(u8**)kbd_tbl2);//显示键盘 } //sim900a GPRS测试 //用于测试TCP/UDP连接 //返回值:0,正常 // 其他,错误代码 u8 sim900a_gprs_test(void) { const u8 *port="8086"; //端口固定为8086,当你的电脑8086端口被其他程序占用的时候,请修改为其他空闲端口 u8 mode=0; //0,TCP连接;1,UDP连接 u8 key; u8 timex=0; u8 ipbuf[16]; //IP缓存 u8 iplen=0; //IP长度 sim900a_gprs_ui(); //加载主界面 Show_Str(30+72,90,200,16,(u8*)modetbl[mode],16,0); //显示连接方式 Show_Str(30+40,130,200,16,(u8*)port,16,0); //显示端口 sim900a_send_cmd("AT+CIPCLOSE=1","CLOSE OK",100); //关闭连接 sim900a_send_cmd("AT+CIPSHUT","SHUT OK",100); //关闭移动场景 if(sim900a_send_cmd("AT+CGCLASS=\"B\"","OK",1000))return 1; //设置GPRS移动台类别为B,支持包交换和数据交换 if(sim900a_send_cmd("AT+CGDCONT=1,\"IP\",\"CMNET\"","OK",1000))return 2;//设置PDP上下文,互联网接协议,接入点等信息 if(sim900a_send_cmd("AT+CGATT=1","OK",500))return 3; //附着GPRS业务 if(sim900a_send_cmd("AT+CIPCSGP=1,\"CMNET\"","OK",500))return 4; //设置为GPRS连接模式 if(sim900a_send_cmd("AT+CIPHEAD=1","OK",500))return 5; //设置接收数据显示IP头(方便判断数据来源) ipbuf[0]=0; while(1) { key=KEY_Scan(); if(key==3) { mode=!mode; //连接模式切换 Show_Str(30+72,90,200,16,(u8*)modetbl[mode],16,0); //显示连接模式 } key=sim900a_get_keynum(0,180); if(key) { if(key<12) { if(iplen<15) { ipbuf[iplen++]=kbd_tbl[key-1][0]; u2_printf("AT+CLDTMF=2,\"%c\"\r\n",kbd_tbl[key-1][0]); } }else { if(key==13)if(iplen)iplen--; //删除 if(key==14&&iplen) //执行GPRS连接 { sim900a_tcpudp_test(mode,ipbuf,(u8*)port); sim900a_gprs_ui(); //加载主界面 Show_Str(30+72,90,200,16,(u8*)modetbl[mode],16,0); //显示连接模式 Show_Str(30+40,130,200,16,(u8*)port,16,0);//显示端口 USART2_RX_STA=0; } if(key==15)break; } ipbuf[iplen]=0; LCD_Fill(30+56,110,239,110+16,WHITE); Show_Str(30+56,110,200,16,ipbuf,16,0); //显示IP地址 } timex++; if(timex==20) { timex=0; LED0=!LED0; } delay_ms(10); sim_at_response(1);//检查GSM模块发送过来的数据,及时上传给电脑 } return 0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// //ATK-SIM900A GSM/GPRS主测试控制部分 //测试界面主UI void sim900a_mtest_ui(u16 x,u16 y) { u8 *p,*p1,*p2; p=mymalloc(SRAMIN,50);//申请50个字节的内存 LCD_Clear(WHITE); POINT_COLOR=RED; Show_Str_Mid(0,y,"ATK-SIM900A 测试程序",16,240); Show_Str(x,y+25,200,16,"请选择:",16,0); Show_Str(x,y+45,200,16,"KEY0:拨号测试",16,0); Show_Str(x,y+65,200,16,"KEY1:短信测试",16,0); Show_Str(x,y+85,200,16,"WK_UP:GPRS测试",16,0); POINT_COLOR=BLUE; USART2_RX_STA=0; if(sim900a_send_cmd("AT+CGMI","OK",200)==0) //查询制造商名称 { p1=(u8*)strstr((const char*)(USART2_RX_BUF+2),"\r\n"); p1[0]=0;//加入结束符 sprintf((char*)p,"制造商:%s",USART2_RX_BUF+2); Show_Str(x,y+110,200,16,p,16,0); USART2_RX_STA=0; } if(sim900a_send_cmd("AT+CGMM","OK",200)==0)//查询模块名字 { p1=(u8*)strstr((const char*)(USART2_RX_BUF+2),"\r\n"); p1[0]=0;//加入结束符 sprintf((char*)p,"模块型号:%s",USART2_RX_BUF+2); Show_Str(x,y+130,200,16,p,16,0); USART2_RX_STA=0; } if(sim900a_send_cmd("AT+CGSN","OK",200)==0)//查询产品序列号 { p1=(u8*)strstr((const char*)(USART2_RX_BUF+2),"\r\n");//查找回车 p1[0]=0;//加入结束符 sprintf((char*)p,"序列号:%s",USART2_RX_BUF+2); Show_Str(x,y+150,200,16,p,16,0); USART2_RX_STA=0; } if(sim900a_send_cmd("AT+CNUM","+CNUM",200)==0) //查询本机号码 { p1=(u8*)strstr((const char*)(USART2_RX_BUF),","); p2=(u8*)strstr((const char*)(p1+2),"\""); p2[0]=0;//加入结束符 sprintf((char*)p,"本机号码:%s",p1+2); Show_Str(x,y+170,200,16,p,16,0); USART2_RX_STA=0; } myfree(SRAMIN,p); } //GSM信息显示(信号质量,电池电量,日期时间) //返回值:0,正常 // 其他,错误代码 u8 sim900a_gsminfo_show(u16 x,u16 y) { u8 *p,*p1,*p2; u8 res=0; p=mymalloc(SRAMIN,50);//申请50个字节的内存 POINT_COLOR=BLUE; USART2_RX_STA=0; if(sim900a_send_cmd("AT+CPIN?","OK",200))res|=1<<0; //查询SIM卡是否在位 USART2_RX_STA=0; if(sim900a_send_cmd("AT+COPS?","OK",200)==0) //查询运营商名字 { p1=(u8*)strstr((const char*)(USART2_RX_BUF),"\""); if(p1)//有有效数据 { p2=(u8*)strstr((const char*)(p1+1),"\""); p2[0]=0;//加入结束符 sprintf((char*)p,"运营商:%s",p1+1); Show_Str(x,y,200,16,p,16,0); } USART2_RX_STA=0; }else res|=1<<1; if(sim900a_send_cmd("AT+CSQ","+CSQ:",200)==0) //查询信号质量 { p1=(u8*)strstr((const char*)(USART2_RX_BUF),":"); p2=(u8*)strstr((const char*)(p1),","); p2[0]=0;//加入结束符 sprintf((char*)p,"信号质量:%s",p1+2); Show_Str(x,y+20,200,16,p,16,0); USART2_RX_STA=0; }else res|=1<<2; if(sim900a_send_cmd("AT+CBC","+CBC:",200)==0) //查询电池电量 { p1=(u8*)strstr((const char*)(USART2_RX_BUF),","); p2=(u8*)strstr((const char*)(p1+1),","); p2[0]=0;p2[5]=0;//加入结束符 sprintf((char*)p,"电池电量:%s%% %smV",p1+1,p2+1); Show_Str(x,y+40,200,16,p,16,0); USART2_RX_STA=0; }else res|=1<<3; if(sim900a_send_cmd("AT+CCLK?","+CCLK:",200)==0) //查询电池电量 { p1=(u8*)strstr((const char*)(USART2_RX_BUF),"\""); p2=(u8*)strstr((const char*)(p1+1),":"); p2[3]=0;//加入结束符 sprintf((char*)p,"日期时间:%s",p1+1); Show_Str(x,y+60,200,16,p,16,0); USART2_RX_STA=0; }else res|=1<<4; myfree(SRAMIN,p); return res; } //sim900a主测试程序 void sim900a_test(void) { u8 key=0; u8 timex=0; u8 sim_ready=0; POINT_COLOR=RED; Show_Str_Mid(0,30,"ATK-SIM900A 测试程序",16,240); while(sim900a_send_cmd("AT","OK",100))//检测是否应答AT指令 { Show_Str(40,55,200,16,"未检测到模块!!!",16,0); delay_ms(800); LCD_Fill(40,55,200,55+16,WHITE); Show_Str(40,55,200,16,"尝试连接模块...",16,0); delay_ms(400); } LCD_Fill(40,55,200,55+16,WHITE); key+=sim900a_send_cmd("ATE0","OK",200);//不回显 sim900a_mtest_ui(40,30); while(1) { delay_ms(10); sim_at_response(1);//检查GSM模块发送过来的数据,及时上传给电脑 if(sim_ready)//SIM卡就绪. { key=KEY_Scan(); if(key) { switch(key) { case 1: sim900a_call_test(); //拨号测试 break; case 2: sim900a_sms_test(); //短信测试 break; case 3: sim900a_gprs_test(); //GPRS测试 break; } sim900a_mtest_ui(40,30); timex=0; } } if(timex==0) //2.5秒左右更新一次 { if(sim900a_gsminfo_show(40,225)==0)sim_ready=1; else sim_ready=0; } if((timex%20)==0)LED0=!LED0;//200ms闪烁 timex++; } } |
中科院
![]()
最后登陆时间:2014-08-02 23:02:45 |
换了一台电脑,终于发上去了,先庆祝一下。
|
此帖由中科院于2014-10-31 17:48:55最后编辑
|
|
中科院
![]()
最后登陆时间:2014-08-02 23:02:45 |
#include <sys/stat.h>
#include <sys/ioctl.h> #include <fcntl.h> #include <linux/spi/spidev.h> #include "Arduino.h" #include "trace.h" #include "SPI.h" #define MY_TRACE_PREFIX "SPI" /* For Arduino, this is assumed to be 4MHz, using SPI_CLOCK_DEV4 * Sticking to this for backward compatibility */ #define SPI_CLK_DEFAULT_HZ 4000000 #define SPI_SS_GPIO_PIN 10 SPIClass SPI; /* Constructor - establish defaults */ SPIClass::SPIClass() { /* reflect Arduino's default behaviour where possible */ this->mode = SPI_MODE0; this->bitOrder = MSBFIRST; this->clkDiv = SPI_CLOCK_DIV4; } void SPIClass::begin() { /* Set the pin mux, for the SCK, MOSI and MISO pins ONLY * * Leave the SS pin in GPIO mode (the application will control it) * but set it's direction to output and initially high */ pinMode(SPI_SS_GPIO_PIN, OUTPUT); digitalWrite(SPI_SS_GPIO_PIN, HIGH); muxSelectSpi(1); this->fd = open(LINUX_SPIDEV, O_RDWR); if (this->fd < 0) { trace_error("Failed to open SPI device\n"); return; } /* Load default/last configuration */ this->setClockDivider(this->clkDiv); this->setBitOrder(this->bitOrder); this->setDataMode(this->mode); } void SPIClass::end() { if (this->fd >= 0) close(this->fd); } void SPIClass::setBitOrder(uint8_t bitOrder) { uint8_t lsbFirst = 0; if (bitOrder == LSBFIRST) { lsbFirst = 1; } if (ioctl (this->fd, SPI_IOC_WR_LSB_FIRST, &lsbFirst) < 0) { trace_error("Failed to set SPI bit justification\n"); return; } this->bitOrder = bitOrder; } void SPIClass::setDataMode(uint8_t mode) { uint8_t linuxSpiMode = 0; switch(mode) { case SPI_MODE0: linuxSpiMode = SPI_MODE_0; break; case SPI_MODE1: linuxSpiMode = SPI_MODE_1; break; case SPI_MODE2: linuxSpiMode = SPI_MODE_2; break; case SPI_MODE3: linuxSpiMode = SPI_MODE_3; break; default: trace_error("Invalid SPI mode specified\n"); return; } if (ioctl (this->fd, SPI_IOC_WR_MODE, &linuxSpiMode) < 0) { trace_error("Failed to set SPI mode\n"); return; } this->mode = mode; } void SPIClass::setClockDivider(uint8_t clkDiv) { uint32_t maxSpeedHz = SPI_CLK_DEFAULT_HZ; /* Adjust the clock speed relative to the default divider of 4 */ switch(clkDiv) { case SPI_CLOCK_DIV2: maxSpeedHz = SPI_CLK_DEFAULT_HZ << 1; break; case SPI_CLOCK_DIV4: /* Do nothing */ break; case SPI_CLOCK_DIV8: maxSpeedHz = SPI_CLK_DEFAULT_HZ >> 1; break; case SPI_CLOCK_DIV16: maxSpeedHz = SPI_CLK_DEFAULT_HZ >> 2; break; case SPI_CLOCK_DIV32: maxSpeedHz = SPI_CLK_DEFAULT_HZ >> 3; break; case SPI_CLOCK_DIV64: maxSpeedHz = SPI_CLK_DEFAULT_HZ >> 4; break; case SPI_CLOCK_DIV128: maxSpeedHz = SPI_CLK_DEFAULT_HZ >> 5; break; default: trace_error("Invalid SPI mode specified\n"); return; } if (ioctl (this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &maxSpeedHz) < 0) { trace_error("Failed to set SPI clock speed\n"); return; } this->clkDiv = clkDiv; } uint8_t SPIClass::transfer(uint8_t txData) { uint8_t rxData = 0xFF; struct spi_ioc_transfer msg; memset(&msg, 0, sizeof(msg)); msg.tx_buf = (__u64) &txData; msg.rx_buf = (__u64) &rxData; msg.len = sizeof(uint8_t); if (ioctl (this->fd, SPI_IOC_MESSAGE(1), &msg) < 0) trace_error("Failed to execute SPI transfer\n"); return rxData; } void SPIClass::transferBuffer(const uint8_t *txData, uint8_t *rxData, uint32_t len) { struct spi_ioc_transfer msg; memset(&msg, 0, sizeof(msg)); msg.tx_buf = (__u64) txData; msg.rx_buf = (__u64) rxData; msg.len = len; if (ioctl (this->fd, SPI_IOC_MESSAGE(1), &msg) < 0) trace_error("Failed to execute SPI transfer\n"); } void SPIClass::attachInterrupt() { trace_error("SPI slave mode is not currently supported\n"); } void SPIClass::detachInterrupt() { /* Do nothing */ } |