zoukankan      html  css  js  c++  java
  • ARM裸机篇串口UART实验

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

    void Uart_SendByte(int data)//这个函数是发送整型数据,参数为data
    {
        if(whichUart==0)//这个是选中串口0
        {
            if(data=='\n')//然后判断数据不为空
            {
          /*寄存器的原始宏定义,
          #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('\r');
            }
            while(!(rUTRSTAT0 & 0x2));   //Wait until THR is empty.
            Delay(10);
            WrUTXH0(data);
        }
        else if(whichUart==1)
        {
            if(data=='\n')
            {
                while(!(rUTRSTAT1 & 0x2));
                Delay(10);                 //because the slow response of hyper_terminal 
                rUTXH1 = '\r';
            }
            while(!(rUTRSTAT1 & 0x2));   //Wait until THR is empty.
            Delay(10);
            rUTXH1 = data;
        }   
        else if(whichUart==2)
        {
            if(data=='\n')
            {
                while(!(rUTRSTAT2 & 0x2));
                Delay(10);                 //because the slow response of hyper_terminal 
                rUTXH2 = '\r';
            }
            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('\n');//打印信息
    	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)
    

     WrUTXH0即是写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端发送数据。

  • 相关阅读:
    Ubuntu 下Apache安装和配置
    MariaDB二进制包简单安装部署
    Ubuntu下MongoDB的安装和使用
    Linux文件类型及目录配置
    centos7下挂载U盘和移动硬盘
    详解 比特(位,bit),字节(Byte),字符的区别 *(转)
    Socket使用及简单实例
    缓存
    字体小图标记录
    大流量下的兜底容灾方案
  • 原文地址:https://www.cnblogs.com/tao560532/p/2280777.html
Copyright © 2011-2022 走看看