数码之家

 找回密码
 立即注册
搜索
查看: 1225|回复: 16

[Arduino] 请教 变量类型转换处理怎么写? 全部转换成为char类型

[复制链接]
发表于 2021-11-16 22:22:32 | 显示全部楼层 |阅读模式

爱科技、爱创意、爱折腾、爱极致,我们都是技术控

您需要 登录 才可以下载或查看,没有账号?立即注册

x
新手学习使用1602  困难多多 :shy:

如果使用液晶显示屏的驱动库 那会简单很多,但有时候可能各种原因会放弃使用库  比如为了减少体积
这也是茶正在尝试的,问题多多 请教各位了

1602的完整手册还没看到过,看TX们好象用到的指令才那么几条  但标准库上貌似有好多条 奇怪我找不到有0x28
1602有没有可以单独清除一行的指令? 不是全屏清除



不同类型的数据转换还没掌握,感觉需要有个函数模块来处理一下 再送给1602处理显示
这会是要用到sprintf吗

请教类型转换怎么写?需要2个,全部转换成为char类型   

1个用来接收数值, 处理转化 整数、浮点、可变长度.....

1个用来接收文本,处理转化 string类型或数组 ....

请TX多多指教 :handshake:

---------------------------------------------------------------------------

目前的处理方式  光标位置和显示内容 目前是分开的

LCD发送指令:void LCD_Send(char d,char RS)  其中d是内容,RS=0 内容为指令,RS=1 内容为显示内容

LCD显示方式:光标位置和显示内容 目前是分开的

*/




void LCD_Cursor(int col,int row){
    int pos,Line;
if (col<16 && row<2){  
      pos=col ; Line=row ;    // col为列位置 ,row=0 第一行,
      if(Line==0) {
        LCD_Send(0x80+pos,0);         // 参数0  发送的是指令
      }
      else {
        LCD_Send(0xC0+pos,0);
      }
}
}


void LCD_Print(char words[16])
{
  int len,count;
    len = strlen(words);
  for (count=0;count<len;count++)
  {
    LCD_Send(words[count],1);       // 参数1  发送的是显示内容
  }

}

新手 :shy:  好些理解可能都是错的   请指正  轻拍 :handshake:







打赏

参与人数 2家元 +40 收起 理由
t3486784401 + 20
qrut + 20

查看全部打赏

发表于 2021-11-16 22:36:54 | 显示全部楼层
不同类型的数据转换还没掌握,感觉需要有个函数模块来处理一下 再送给1602处理显示
这会是要用到sprintf吗
请教类型转换怎么写?需要2个,全部转换成为char类型   
1个用来接收数值, 处理转化 整数、浮点、可变长度.....
1个用来接收文本,处理转化 string类型或数组 ....


这些是C/C++的基础知识。

在单片机中,往往是比较单一的转换,所以通常自己写转换的过程。


转换还要看需要的哪种结果,

如int 转 char*(二进制),int a=0x1234; 直接可以 ( char * ) a;

如果是转成十进制字符,有些限制,如4位数
ch[3]  = (a/1000)%10 + '0';
ch[2]  = (a/100)%10 + '0';
ch[1]  = (a/10)%10 + '0';
ch[0]  = a/%10 + '0';

如想转十六进制字符,这你自己考虑一下吧。
回复 支持 反对

使用道具 举报

发表于 2021-11-16 22:50:37 | 显示全部楼层
我也是新手,我用汇编语言的风格写的LCD1602程序
可参考如下

使用说明: 数组  unsigned char xdata LCD1602RAM1[2][16] 就是对应LCD1602两行,每行16字, 对这数组某位写入ASCII码就可以在LCD1602对应位上显示出来
LCD_SC1(); 这个函数就是写入需要显示的数据ASCII码,   
LCD1602SC();        这个函数是把数组  unsigned char xdata LCD1602RAM1[2][16]  的数据逐个写入到LCD1602

//-------------------------------------------
        #include<stc8g.h>
        #include  "intrins.h"


   sbit LCD_D0  =  P1^2;
   sbit  LCD_D1  =  P1^3 ;
   sbit  LCD_D2  =  P3^2 ;
   sbit  LCD_D3  =  P3^3 ;
   sbit  LCD_D4  =  P3^4 ;
   sbit  LCD_D5  =  P3^5 ;
   sbit  LCD_D6  =  P3^6 ;
   sbit  LCD_D7  =  P3^7;
   sbit  LCD_RS  =  P1^0;   //LCD1602 的 RS端  ,1-数据,0-指令
   sbit  LCD_EN  =  P1^1 ;  //LCD1602 的 E端   ,先从低变高,再变低,以确认输入数据或命令


         unsigned char xdata LCD1602RAM1[2][16]={
         {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20},                  //LCD1602的缓存,初始值是空格20H
         {0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20}
         };


         unsigned char bdata LCD1602RAM2;  //LCD1602的写入缓冲
         sbit LCD1602RAM2_D0= LCD1602RAM2^0;
         sbit LCD1602RAM2_D1= LCD1602RAM2^1;
         sbit LCD1602RAM2_D2= LCD1602RAM2^2;
         sbit LCD1602RAM2_D3= LCD1602RAM2^3;
         sbit LCD1602RAM2_D4= LCD1602RAM2^4;
         sbit LCD1602RAM2_D5= LCD1602RAM2^5;
         sbit LCD1602RAM2_D6= LCD1602RAM2^6;
         sbit LCD1602RAM2_D7= LCD1602RAM2^7;


         void LCD1602ZL();  //LCD1602指令写入函数
           void LCD1602SZ();  //LCD1602数据写入函数
         void LCD1602CCH();  //LCD1602初始化函数
         void LCD1602SC();        //LCD1602全屏写入函数

         void LCD_SC1()     //全屏数据显示程序      ,需要显示的数据

         #define     MAIN_Fosc       11059200L   //定义主时钟,  自定义变量 ,L是长整型的意思

        void main()
        {


                  LCD1602CCH();                //LCD1602初始化

              //主函数//********************
            while (1)       //下面重复循环
       {

           LCD1602SC();           //LCD1602全屏写入函数
           LCD_SC1();    //全屏数据显示程序      ,需要显示的数据
      }

}



                         //LCD1602指令写入
                        void LCD1602ZL()
                        {
                        LCD_RS=0;
                        LCD_EN=1;
                   LCD_D0=LCD1602RAM2_D0;
                   LCD_D1=LCD1602RAM2_D1;
                   LCD_D2=LCD1602RAM2_D2;
                   LCD_D3=LCD1602RAM2_D3;
                   LCD_D4=LCD1602RAM2_D4;
                   LCD_D5=LCD1602RAM2_D5;
                   LCD_D6=LCD1602RAM2_D6;
                   LCD_D7=LCD1602RAM2_D7;
                    LCD_EN=0;                 //E,下降沿,让LCD读取
                        Delay60us();  //延时80us

                        }

                 //LCD1602数据写入
                        void LCD1602SZ()
                   {
                         LCD_RS=1;
                        LCD_EN=1;
                   LCD_D0=LCD1602RAM2_D0;
                   LCD_D1=LCD1602RAM2_D1;
                   LCD_D2=LCD1602RAM2_D2;
                   LCD_D3=LCD1602RAM2_D3;
                   LCD_D4=LCD1602RAM2_D4;
                   LCD_D5=LCD1602RAM2_D5;
                   LCD_D6=LCD1602RAM2_D6;
                   LCD_D7=LCD1602RAM2_D7;
                    LCD_EN=0;  //E,下降沿,让LCD读取
                         Delay60us();  //延时80us

                        }

                        //LCD1602初始化
                        void LCD1602CCH()
                        {
                       
                        LCD1602RAM2=0;
                        delay_ms(15);          //延时15毫秒
                        LCD1602RAM2=0x38;  //;16行*2,5*8
                        LCD1602ZL();         //写入指令
                   delay_ms(5);          //延时5毫秒
                   LCD1602RAM2=0x38;  //;16行*2,5*8
                        LCD1602ZL();         //写入指令
                   delay_ms(5);          //延时5毫秒
                   LCD1602RAM2=0x08; // 关显示
                   LCD1602ZL();         //写入指令
                   delay_ms(1);          //延时1毫秒
                  LCD1602RAM2=0x01;        //清屏
                   LCD1602ZL();         //写入指令
                   delay_ms(5);          //延时5毫秒
                   LCD1602RAM2=0x06;        //;地址计数器AC自动加1,光标右移 *******
                   delay_ms(1);          //延时1毫秒
                   LCD1602RAM2=0x0C;        //开显示
                  LCD1602ZL();         //写入指令
                   delay_ms(1);          //延时1毫秒
                  
                   }


                        // LCD1602全屏显示程序,16字*2行

                  void LCD1602SC()
                   {
                   unsigned char i=16;          //每行的个数计数
                   unsigned char x=0;                 //行数
                   unsigned char y=0;                //列数
                  
                   LCD1602RAM2=0x80;   //这个是LCD第1行的地址
                   LCD1602ZL(); //以地址/指令形式发送到LCD1602

                   while(i--)
                   {
                   LCD1602RAM2=LCD1602RAM1[0][y];
                   LCD1602SZ(); //以数据形式发送到LCD1602
                   y++;
                   };

               LCD1602RAM2=0xC0;   //这个是LCD第2行的地址
                   LCD1602ZL(); //以地址/指令形式发送到LCD1602
                   i=16        ;                 //每行的个数计数
                   y=0;        //每行的个数
                   while(i--)
                   {
                   LCD1602RAM2=LCD1602RAM1[1][y];
                   LCD1602SZ(); //以数据形式发送到LCD1602
                   y++;
                   };
                  
                   }




                   void LCD_SC1()     //全屏数据显示程序      ,需要显示的数据
                     {
                        LCD1602RAM1[0][0] =ON_DAY10+0X30;         //开机时的日十位
                        LCD1602RAM1[0][1] =ON_DAY1+0X30;           //开机时的日个位
                        LCD1602RAM1[0][2] ='/';                  //分隔符

                        LCD1602RAM1[0][3] =ON_HOUR10+0X30;  //开机时的时十位
                        LCD1602RAM1[0][4] =ON_HOUR1+0X30;           //开机时的时个位
                        LCD1602RAM1[0][5] =':';                  //分隔符
                        LCD1602RAM1[0][6] =ON_MIN10+0X30;        //开机时的分十位
                        LCD1602RAM1[0][7] =ON_MIN1+0X30;        //开机时的分个位

                        LCD1602RAM1[0][8] =0x2d;  //符号-
                        LCD1602RAM1[0][9] =0x7e;  //符号 >


                        LCD1602RAM1[0][10] =OFF_HOUR10+0X30; //停机时的时十位
                        LCD1602RAM1[0][11] =OFF_HOUR1+0X30;           //停机时的时个位
                        LCD1602RAM1[0][12] =':';                  //分隔符  
                        LCD1602RAM1[0][13] =OFF_MIN10+0X30;        //停机时的分十位
                        LCD1602RAM1[0][14] =OFF_MIN1+0X30;        //停机时的分个位
                                           
                        LCD1602RAM1[0][15] =0X20; //空格


                        LCD1602RAM1[1][0] =(RUN1_HOUR/1000%10) +0x30;        //保养运行时间的小时千位
                        LCD1602RAM1[1][1] =(RUN1_HOUR/100%10) +0x30;        //保养运行时间的小时百位
                        LCD1602RAM1[1][2] =(RUN1_HOUR/10%10) +0x30;        //保养运行时间的小时十位
                        LCD1602RAM1[1][3] =(RUN1_HOUR%10) +0x30;        //保养运行时间的小时个位         
                        LCD1602RAM1[1][4] =  ':';                  //分隔符
                        LCD1602RAM1[1][5] =        (RUN1_MIN/10%10)+0x30;         //运行时间分钟十位
                        LCD1602RAM1[1][6] =        (RUN1_MIN%10)+0x30;         //运行时间分钟个位

                        LCD1602RAM1[1][7] =        '&';
                        LCD1602RAM1[1][8] =        '&';
                        LCD1602RAM1[1][9] =  
                        LCD1602RAM1[1][10] =  (EEPROM_RW[19]/100%10) +0x30;        //上次当日运行时间小时百位
                        LCD1602RAM1[1][11] = (EEPROM_RW[19]/10%10) +0x30;        //上次当日运行时间小时十位
                        LCD1602RAM1[1][12] = (EEPROM_RW[19]%10) +0x30;        //上次当日运行时间小时个位

                        LCD1602RAM1[1][13] =  ':';                  //分隔符
                        LCD1602RAM1[1][14] =EEPROM_RW[18]/10%10+0x30;        //上次当日运行时间分钟个位

                        LCD1602RAM1[1][15] =EEPROM_RW[18]%10+0x30;        //上次当日运行时间分钟十位
                               

                             }


         //下面是延时函数***********************

                void Delay60us()                //@11.0592MHz
        {
        unsigned char i, j;

        _nop_();
        i = 1;
        j = 162;
        do
        {
                while (--j);
        } while (--i);
        }

         void delay_ms(unsigned int ms)                 //延时函数,ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
{
     unsigned int i;
     do{
          i = MAIN_Fosc / 13000;
          while(--i)    ;   //14T per loop
     }while(--ms);
}











回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-16 22:54:13 | 显示全部楼层
devcang 发表于 2021-11-16 22:36
这些是C/C++的基础知识。

在单片机中,往往是比较单一的转换,所以通常自己写转换的过程。

热心坛友!  :handshake:

基础知识欠缺太多 :loveliness:  
太笨 记性也不好 唉


回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-16 23:22:15 | 显示全部楼层
广东梁百万 发表于 2021-11-16 22:50
我也是新手,我用汇编语言的风格写的LCD1602程序
可参考如下

传说中的汇编 :handshake:   厉害了

         void LCD1602SC();        //LCD1602全屏写入函数
         void LCD_SC1()     //全屏数据显示程序      ,需要显示的数据

这2个是跨行显示用的吧?  我还没用过

:praise: 老兄的时钟越来越棒了





回复 支持 反对

使用道具 举报

发表于 2021-11-17 00:29:54 | 显示全部楼层
devcang 发表于 2021-11-16 22:36
这些是C/C++的基础知识。

在单片机中,往往是比较单一的转换,所以通常自己写转换的过程。

如果是转成十进制字符,有些限制,如4位数
ch[3]  = (a/1000)%10 + '0';   //写错了,正确应该是:ch[3]  = a % 10000 / 1000 + '0';
ch[2]  = (a/100)%10 + '0';     //写错了,正确应该是:ch[2]  = a % 1000 / 100 + '0';
ch[1]  = (a/10)%10 + '0';      //写错了,正确应该是:ch[1]  = a % 100 / 10 + '0';
ch[0]  = a/%10 + '0';            //这行终于写对了

以上只有最后一行是对的,其它他是错的,你是想误导楼主吗?
回复 支持 反对

使用道具 举报

发表于 2021-11-17 09:20:25 | 显示全部楼层
595953427@qq 发表于 2021-11-17 00:29
如果是转成十进制字符,有些限制,如4位数
ch[3]  = (a/1000)%10 + '0';   //写错了,正确应该是:ch[3]  ...


实践了,才知道对错
回复 支持 反对

使用道具 举报

发表于 2021-11-17 10:59:35 | 显示全部楼层
devcang 发表于 2021-11-17 09:20
实践了,才知道对错

确实可以,你这种写法还真是第一次见到。:praise:
回复 支持 1 反对 0

使用道具 举报

发表于 2021-11-17 12:42:56 来自手机浏览器 | 显示全部楼层
void LCD_Print(char words[16])
因为是固定长度显示,不如像3楼那样直接使用全局变量,
这样容易实现滚动或切换显示,统一显示控制
里面也不用strlen,固定16*2个字符循环
回复 支持 反对

使用道具 举报

发表于 2021-11-17 13:14:40 | 显示全部楼层
595953427@qq 发表于 2021-11-17 10:59
确实可以,你这种写法还真是第一次见到。

Welcome!

很多时候,针对数据类型、编译器,做计算方法。
回复 支持 反对

使用道具 举报

发表于 2021-11-17 15:44:37 | 显示全部楼层
595953427@qq 发表于 2021-11-17 00:29
如果是转成十进制字符,有些限制,如4位数
ch[3]  = (a/1000)%10 + '0';   //写错了,正确应该是:ch[3]  ...

其实说白了就是分别求余数然后挪到个位
回复 支持 反对

使用道具 举报

发表于 2021-11-17 15:46:18 | 显示全部楼层
本帖最后由 icec 于 2021-11-17 16:16 编辑

翻个祖传代码出来,这个是当年整数控电源时搞的个代码,用结构体来拆解和组合数字
变量转字符只要提取先出数字的每一位,再变成char里对应的数字
class dat
{
   public:
//数字里的个十百千
      uint8 q =0 ;  //千
      uint8 b =0 ;   //百
      uint8 s =0 ;//十
      uint8 g =0;//个
  
      int lim=32768;//数字最大值限制,防止参数超限

      int sum ;//数字本身

      void chaidat( );//拆解函数,重点

      int sumdat();//用来将每一位重新组合
};
int dat::sumdat(void)//用来将每一位重新组合
{   sum=(q*1000)+(b*100)+ ( s*10) +g;
    if(sum>lim)sum=lim;
    return sum ;
}
//拆解函数,重点
void dat::chaidat(){

//以3258为例
  g=sum%10;           //个位就是直接取它和十的余数
// 3258%10=8  
  s=sum/10%10;     //十位就先除十再求余数   
//3258/10=325(全部为整形,小数丢弃) 325%10=5  
  b=sum/100%10;                   //百位就先除百再求余数   
//3258/100=32(全部为整形,小数丢弃) 32%10=2
  q=sum/1000%10;                   //千位就先除千再求余数   
//3258/1000=3 (全部为整形,小数丢弃) 3%10=3
  }

  //------


dat usat;
提取出int型的每一位之后就简单了,就是上面@595953427@qq 的方法里最后面的  +'0'    原理很简单,其实就是转成ascii中的各个数字的编号//'0' 就是0 的ascii



然后一个个输出字符就好了










回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 16:23:24 | 显示全部楼层
595953427@qq 发表于 2021-11-17 10:59
确实可以,你这种写法还真是第一次见到。

一起学习 :handshake:

回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 16:24:38 | 显示全部楼层
icec 发表于 2021-11-17 15:46
翻个祖传代码出来,这个是当年整数控电源时搞的个代码,用结构体来拆解和组合数字
变量转字符只要提取先出数 ...

一再帮助 非常感谢 !:handshake:

这些我得好好学习消化下
基础比较差 :shy:

回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 16:27:02 | 显示全部楼层
kaixi_ants 发表于 2021-11-17 12:42
void LCD_Print(char words[16])
因为是固定长度显示,不如像3楼那样直接使用全局变量,
这样容易实现滚动 ...

感谢帮助! :handshake:

准备学习下重新开始





回复 支持 反对

使用道具 举报

发表于 2021-11-17 18:53:09 | 显示全部楼层
茶壹杯 发表于 2021-11-17 16:24
一再帮助 非常感谢 !

这些我得好好学习消化下

其实那一堆重点主要是,如何提出数字的`每一位.复制多了
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 19:22:05 | 显示全部楼层
icec 发表于 2021-11-17 18:53
其实那一堆重点主要是,如何提出数字的`每一位.复制多了

很经典的方法 :handshake:

谢谢给找了那么多的资料 :handshake:
够我学一阵子了


   
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

APP|手机版|小黑屋|关于我们|联系我们|法律条款|技术知识分享平台

闽公网安备35020502000485号

闽ICP备2021002735号-2

GMT+8, 2025-5-9 02:46 , Processed in 0.296401 second(s), 12 queries , Redis On.

Powered by Discuz!

© 2006-2025 MyDigit.Net

快速回复 返回顶部 返回列表