历史上的今天
返回首页

历史上的今天

今天是:2024年10月22日(星期二)

正在发生

2019年10月22日 | ARM裸机篇-串口UART实验

2019-10-22 来源:51hei

串口应该都很熟悉了,具体通信原理我就不提了,这个百度上都很多讲的,然后就直接看函数了。

void Uart_SendByte(int data)//这个函数是发送整型数据,参数为data

{

    if(whichUart==0)//这个是选中串口0

    {

        if(data=='')//然后判断数据不为空

        {

      /*寄存器的原始宏定义,

      #define rUTRSTAT0   (*(volatile unsigned *)0x50000010) //UART 0 Tx/Rx status*/

            while(!(rUTRSTAT0 & 0x2));/*这个就是查询串口0的状态寄存器,第1位是发送缓冲器是否为空

            第二位是Transmit buffer empty

            0 = The buffer register is not empty

            1 = Empty     这里检查为0的话就是还没发送完全,当置1的时候表示发完了,程序继续执行*/

            Delay(10);                 //because the slow response of hyper_terminal

            WrUTXH0('');

        }

        while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.

        Delay(10);

        WrUTXH0(data);

    }

    else if(whichUart==1)

    {

        if(data=='')

        {

            while(!(rUTRSTAT1 & 0x2));

            Delay(10);                 //because the slow response of hyper_terminal

            rUTXH1 = '';

        }

        while(!(rUTRSTAT1 & 0x2));   //Wait until THR is empty.

        Delay(10);

        rUTXH1 = data;

    }   

    else if(whichUart==2)

    {

        if(data=='')

        {

            while(!(rUTRSTAT2 & 0x2));

            Delay(10);                 //because the slow response of hyper_terminal

            rUTXH2 = '';

        }

        while(!(rUTRSTAT2 & 0x2));   //Wait until THR is empty.

        Delay(10);

        rUTXH2 = data;

    }      

}


搞了这么久我还不知道如何确定ARM的大端或是小端格式,这个是在启动代码里设置的,现在还没看,mini2440的串口代码和华恒2410的串口发送代码一样的。注释如上。


主函数中的关键代码:

/***************************************************************************************

*   Function Name               :   Main()

*   Create Date                 :   2011/12/10

*   Author/Corporation          :   涛行天下

*

*   Description                 :   Find a proper thread in thread array

*

*   Param                       :   ThreadNo : someParam description

                                    ThreadStaus : someParam description

*

*

*   Global Variable             :   DISP_wuiSegmentAppID

*   File Static Variable                :   naucThreadNo

*   Function Static Variable        :   None

*   

*----------------------------------------------------

*   Revision History

*   No.         Date          Revised by                 Item       Description

*   V0.0           2011/12/10     涛行天下          ...         ....

***************************************************************************************/

void Main(void)

{

    U8 count_num = 0;

    char *mode;

    int i;

    U8 key;

    U32 mpll_val = 0 ;

    //U32 divn_upll = 0 ;


    #if ADS10   

//  __rt_lib_init(); //for ADS 1.0

    #endif


    Port_Init();//端口初始化


    Isr_Init();//中断初始化


    i = 2 ; //don't use 100M!

        //boot_params.cpu_clk.val = 3;

    //确定频率

    switch ( i )

    {

        case 0: //200

            key = 12;

            mpll_val = (92<<12)|(4<<4)|(1);

            break;

        case 1: //300

            key = 13;

            mpll_val = (67<<12)|(1<<4)|(1);

            break;

        case 2: //400

            key = 14;

            mpll_val = (92<<12)|(1<<4)|(1);

            break;

        case 3: //440!!!

            key = 14;

            mpll_val = (102<<12)|(1<<4)|(1);

            break;

        default:

            key = 14;

            mpll_val = (92<<12)|(1<<4)|(1);

            break;

    }


    //init FCLK=400M, so change MPLL first

    ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);

    ChangeClockDivider(key, 12);

    cal_cpu_bus_clk();


    consoleNum = 0; // Uart 1 select for debug.选择串口号

    Uart_Init( 0,115200 );//初始化串口参数以及时钟源

    Uart_Select( consoleNum );//选择串口号


    Beep(2000, 100);//蜂鸣器


    Uart_SendByte('');//打印信息

    Uart_SendByte('H');

    while(1)

    {

        Uart_SendByte(count_num);

        Uart_SendByte(' ');

        count_num ++;

        Delay(500);

    }

从而让ARM一直向PC机发送从0-255数据,在PC机中显示结果如下:
 
这个看不了十六进制的数,我搞了个串口助手来显示:
 
上面那个是用mini2440实现的,那个通过UBOOT可以直接烧写程序,不过到了华恒的板子我就不知道为啥了,这个苦闷了我好久,今天在进入PPCBOOT中利用erase命令把那个linux系统檫除了,然后进入ppcboot命令行形式才可以jtag调试,不知道为啥,这次终于进了一次调试结果出来了。
 
 
下面出一张计数的图,感觉下成就感吧,虽然底层函数还没完全弄懂!
 
现在总结这些步骤吧,最开始在上电的时候不要立马启动系统,先要进入PPCBOOT模式命令行,然后再启动AXD调试器。
 
通过H-JATG软件可以看到是小端格式的,但是具体怎么设置暂时还不清楚,

#define WrUTXH0(ch) (*(volatile unsigned char *)0x50000020)=(unsigned char)(ch)


rUTXH0即是写UTXH0的意思,UTXH0是第一个串口的发送缓冲寄存器!

2011/12/13日

还是阿南的程序给力啊,华恒板子带的程序没啥用

2011/12/21日

感慨日子过的飞快啊!可是我却没啥长进,先上程序吧:


;//呼叫主应用程序

    b UART

UART

    ldr r0, =GPHCON ;//设置RxD0,TxD0引脚

    ldr r1, =0x2afaaa

    str r1, [r0]

     

    ldr r0, =GPHUP

    ldr r1, =0x7ff

    str r1, [r0] ;    // The pull up function is disabled GPH[10:0]



    ldr r0, =UFCON0 ;//禁用FIFO

    ldr r1, =0x0

    str r1, [r0]

   

    ldr r0, =UMCON0  ;//禁用AFC

    ldr r1, =0x0

    str r1, [r0]

     

    ldr r0, =ULCON0 ;//设置线寄存器

    ldr r1, =0x3   ; //UART LINE CONFIG  正常模式,无奇偶校验,一个停止位,8个数据位

    str r1, [r0]

     

    ldr r0, =UCON0 ;//设置Uart0控制器

    ldr r1, =0x245;//RX边沿触发,TX电平触发,禁用延时中断,使用RX 错误中断,正常操作模式,中断请求或表决模式

    str r1, [r0]

     

    ldr r0, =UBRDIV0 ;//设置波特率为115200

    ldr r1, =0x1a    ;//int(50700000 / 16 / 115200) - 1 = 26

    str r1, [r0]

     

    mov r1, #100

Delay

    sub r1, r1, #0x1

    bne Delay

     

    ;//开中断

    ldr r0, =INTMSK

    ldr r1, [r0]

    and r1, r1, #0xefffffff

    str r1, [r0]

     

    MOV R5 , #127 ;//设置要打印的字符的个数

    MOV R1 , #0x0 ;//设置要打印的字符

LOOP  

   LDR R3 , =UTRSTAT0

   LDR R2 , [R3]

   TST R2 ,#0x04 ;//判断发送缓冲区是否为空

   BEQ LOOP      ;//为空则执行下边的语句,不为空则跳转到LOOP

   LDR R0 , =UTXH0

   

   STR R1 ,[R0] ;//向数据缓冲区放置要发送的数据

   ADD R1, R1, #1

   SUB R5 ,R5, #0x01 ;//计数器减一

   CMP R5 ,#0x0

   BNE LOOP

   

LOOP2   B LOOP2


这个紧跟随这启动代码后面的一部分用汇编编的串口发送程序,设置相关寄存器,然后往PC端发送数据。


推荐阅读

史海拾趣

BLACK&DECKER公司的发展小趣事

BLACK&DECKER公司的历史可以追溯到1910年,由Alonzo G. Decker和Duncan S. Black在美国马里兰州巴尔的摩共同创立。两位创始人的初始投资来自于Black先生卖掉他的二手车所得的600美元,再加上1200美元的贷款。公司起初主要生产牛奶瓶装盖机、棉花采集机、糖果浸包机等工业用设备。然而,真正让BLACK&DECKER崭露头角的,是1916年他们发明的现代手枪钻原型。这一创新产品解决了当时德国电动工具笨重、难以操控的问题,为电动工具行业带来了革命性的变革。

Collins Electronics Corp公司的发展小趣事

在电子行业竞争日益激烈的情况下,Collins Electronics Corp面临着巨大的挑战。为了保持竞争优势,公司加大了研发投入,不断优化产品性能。同时,他们还加强了对市场趋势的研究,以便及时调整产品策略。在一次行业技术革新中,公司凭借敏锐的市场洞察力和强大的研发能力,成功推出了一款符合市场需求的新产品,赢得了市场份额。

Anytek Technology Corporation Ltd公司的发展小趣事

随着技术实力的不断提升和市场份额的稳步增长,Anytek在2009年获得了“中国国际高新技术企业”的认定。这一荣誉不仅是对公司技术实力和创新能力的肯定,也为公司的未来发展提供了更广阔的空间和机遇。同年,Anytek还成功进入了俄罗斯政府采购项目,进一步扩大了公司的国际影响力。

Equinox公司的发展小趣事

随着科技的发展,Equinox意识到数字化对于提升客户体验的重要性。因此,公司开始投入大量资源建设数字平台,提供在线预约、课程购买、健康管理等服务。这些数字化功能不仅方便了客户,还提高了公司的运营效率。

国产公司的发展小趣事
采用高质量的元器件,合理设计电路的布局和走线,以减少信号路径上的干扰和损耗。
Dresden Elektronik公司的发展小趣事

Dresden Elektronik公司始终将产品质量放在首位。他们建立了严格的质量管理体系,从原材料采购到生产、检测、包装等各个环节都严格把关。这种对品质的执着追求使公司的产品在市场上赢得了良好的口碑,也为公司赢得了众多忠实的客户。

问答坊 | AI 解惑

用数码管做的时钟: 似乎就是不能加上闹铃的!

用数码管做的时钟: 似乎就是不能加上闹铃功能的! 理由是: 跟显示冲突了! 是这样么?有没有朋友做成的呢?…

查看全部问答>

系统挂起问题

我有两个问题想请教各位 1.为何我点击‘开始’-‘挂起’后,屏幕的背景灯一直不灭?如何才能使屏幕在点击‘挂起’后就能关闭? 2.我在外部设置了一个按键,按下它则系统进入挂起,再按则被唤醒,该功能已做通,为何我点‘开始’中的‘挂起’后无 ...…

查看全部问答>

PB 5错误信息 Too much data space used by DLL's in MODULES section

Error: Too much data space used by DLL\'s in MODULES section   Current usage = 28032k, Maximum usage = 26624k.   Reduce DLL usage or move some DLL\'s into the FILES section. 能否增大这个 max usage??…

查看全部问答>

VS2005开发CE4.2程序的疑问

请问可以用VS2005使用C++语言但不使用.NET CF开发CE4.2程序吗 看到里面有个 工程选项是 SmartDevice 进去后SDK只能选POCKET PC2003和Smartphone2003 我自己装的WCE400的SDK没显示出来,而且上面2个SDK对应的处理器都是ARMV4 在EVC4中处理器是可 ...…

查看全部问答>

STM32接TFTLCD如何放连续图片?

                                 按照AN2790文档的说明,以240*320为例,放一幅图片需要150K,如需要放动画则需要在flash中存放N*150K的数据,有没 ...…

查看全部问答>

05.17【每日一问】:电信日一天

    5.17是世界电信日。     随着电报的发明,信息的传递方便、快捷起来,人类也因此进入了电信时代。为使电报发挥更大的作用,1865年5月17日,法国、德国、俄国、意大利、奥地利等20多个国家在法国巴黎签订了 ...…

查看全部问答>

APA600 内核电流异常

选用的APA600的片子,但是设备一加热,内核功耗就上去了,测了测大概电流大了14mA,温度降下来就正常了,哪位大侠用过这型的片子,指点一二吧,不胜感激…

查看全部问答>

数据手册离你有多远??

一般,我们看数据手册都是为了看数据手册上的一些重要参数,但是: 这些参数是真的吗? 也就是说该芯片真的能做到数据手册上所说的那些指标吗? 还是我们自己的原因使得该芯片不能达到数据手册所标榜的参数? 或者是说芯片生产商“夸大”了芯片 ...…

查看全部问答>

proteus7.7

proteus7.7安装了不可用 …

查看全部问答>