CSDN仅用于增加百度收录权重,排版未优化,日常不维护。请访问:www.hceng.cn 查看、评论。
本博文对应地址: https://hceng.cn/2017/07/28/AM437x——LED裸机/#more
最近在玩AM437X,记录下一些学习过程。分为裸机和驱动。
0.准备文件
- AM437x EVM Schematic(后称原理图YP)
- am4378(后称芯片手册SP)
- spruhl7g(后称参考手册CP)
1.分析原理图
四个LED灯,单片机通过控制三极管的通断,从而控制灯的亮灭。
单片机高电平,三极管打通,灯亮,反之低电平,LED灭。
D7_Blue 对应uart3_txd(GPIO5_3);
D8_Blue 对应uart3_rxd(GPIO5_2);
D9_Green 对应uart3_rtsn(GPIO5_1);
D10_Red 对应uart3_ctsn(GPIO5_0);
2.编写程序
1.使能GPIO外设时钟;
{% codeblock lang:c%}
PRCM_CM_PER_GPIO5_CLKCTRL = (0x01<<1);
{% endcodeblock %}
2.设置GPIO模式(默认使能了上拉,且为GPIO模式);
{% codeblock lang:c%}
CTRL_CONF_UART3_RXD &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);//使能上/下拉、关闭输入
CTRL_CONF_UART3_RXD |= (0x7<<0 | 0x01<<17);//IO模式,设置上拉
CTRL_CONF_UART3_TXD &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);//使能上/下拉、关闭输入
CTRL_CONF_UART3_TXD |= (0x7<<0 | 0x01<<17);//IO模式,设置上拉
CTRL_CONF_UART3_RTSN &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);//使能上/下拉、关闭输入
CTRL_CONF_UART3_RTSN |= (0x7<<0 | 0x01<<17);//IO模式,设置上拉
CTRL_CONF_UART3_CTSN &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);//使能上/下拉、关闭输入
CTRL_CONF_UART3_CTSN |= (0x7<<0 | 0x01<<17);//IO模式,设置上拉
{% endcodeblock %}
3.设置为输出;
{% codeblock lang:c%}
GPIO5->OE &= ~(0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);
{% endcodeblock %}
4.设置允许输出位;
{% codeblock lang:c%}
GPIO5->SETDATAOUT |= (0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);
{% endcodeblock %}
5.设置输出值;
{% codeblock lang:c%}
GPIO5->DATAOUT |= (0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);//高
GPIO5->DATAOUT &= ~(0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);//低
{% endcodeblock %}
6.封装成函数;
将前面的1-4步,封装为void led_init(void);
{% codeblock lang:c%}
void led_init(void)
{
PRCM_CM_PER_GPIO5_CLKCTRL = (0x01<<1);
CTRL_CONF_UART3_RXD &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);
CTRL_CONF_UART3_RXD |= (0x7<<0 | 0x01<<17);
CTRL_CONF_UART3_TXD &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);
CTRL_CONF_UART3_TXD |= (0x7<<0 | 0x01<<17);
CTRL_CONF_UART3_RTSN &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);
CTRL_CONF_UART3_RTSN |= (0x7<<0 | 0x01<<17);
CTRL_CONF_UART3_CTSN &= ~(0x7<<0 | 0x01<<16 | 0x01<<17 | 0x01<<18);
CTRL_CONF_UART3_CTSN |= (0x7<<0 | 0x01<<17);
GPIO5->OE &= ~(0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);
GPIO5->SETDATAOUT |= (0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);
}
{% endcodeblock %}
将前面的第5步根据需求,封装成分别操作每个灯;
总开关(1开0关):
{% codeblock lang:c%}
void led_switch(unsigned char on_off)
{
if(on_off)
GPIO5->DATAOUT |= (0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);
else
GPIO5->DATAOUT &= ~(0x01<<0 | 0x01<<1 | 0x01<<2 | 0x01<<3);
}
{% endcodeblock %}
每个灯的独立开关(1开0关):
{% codeblock lang:c%}
void led0_switch(unsigned char on_off)
{
if(on_off)
GPIO5->DATAOUT |= (0x01<<0);
else
GPIO5->DATAOUT &= ~(0x01<<0);
}
void led1_switch(unsigned char on_off)
{
if(on_off)
GPIO5->DATAOUT |= (0x01<<1);
else
GPIO5->DATAOUT &= ~(0x01<<1);
}
void led2_switch(unsigned char on_off)
{
if(on_off)
GPIO5->DATAOUT |= (0x01<<2);
else
GPIO5->DATAOUT &= ~(0x01<<2);
}
void led3_switch(unsigned char on_off)
{
if(on_off)
GPIO5->DATAOUT |= (0x01<<3);
else
GPIO5->DATAOUT &= ~(0x01<<3);
}
{% endcodeblock %}
3.下载设置
AM437X支持多种方式启动,比如:flash memory, memory cards and UART, USB, or Ethernet.以后估计使用U盘和SD卡的情况居多。
U盘和SD卡启动对image有一定的格式要求,需要加个头信息。该部分在参考手册5.2.9 Image Format有介绍,后面有时间再分析。
这里直接用现成的tiimage.c进行加头操作。tiimage.c和程序的交叉编译,都是在Linux进行的,需要做如下步骤:
1.清理,交叉编译;
2.编译,加头;
3.重命名;
4.复制到SD卡(U盘);
为了方便,写了脚本完成以上操作,只需要插上U盘(Windows下),然后ssh登陆执行脚本即可。关于工作流的想法,后面找个时间写写。
{% codeblock lang:bash [hceng_am437x_create_MLO.sh] https://github.com/hceng/learn/blob/master/shell/hceng_am437x_create_MLO.sh%}
#!/bin/bash
myPath="/mnt/hgfs/windows/" #利用虚拟机"文件共享"WindowsU盘的路径
RED_COLOR=’\E[1;31m’ #红
GREEN_COLOR=’\E[1;32m’ #绿
YELOW_COLOR=’\E[1;33m’ #黄
BLUE_COLOR=’\E[1;34m’ #蓝
PINK=’\E[1;35m’ #粉红
RES=’\E[0m’ #END
#生成MLO
function creat_MLO()
{
rm -f /mnt/hgfs/windows/MLO
make clean
make
gcc ./image_tool/tiimage.c -o tiimage.out
./tiimage.out 0x40300000 MMCSD am437x_hardware.bin /mnt/hgfs/windows/MLO
rm -f *.dis *.bin *.o *_elf tiimage.out
ls /mnt/hgfs/windows/MLO -l && echo -e “
G
R
E
E
N
C
O
L
O
R
=
=
=
=
=
=
M
L
O
O
K
!
=
=
=
=
=
=
{GREEN_COLOR}======MLO OK!======
GREENCOLOR======MLOOK!======{RES}”
|| echo -e “
R
E
D
C
O
L
O
R
=
=
=
=
=
=
M
L
O
E
R
R
O
R
!
=
=
=
=
=
=
{RED_COLOR}======MLO ERROR!======
REDCOLOR======MLOERROR!======{RES}”
sync
}
#判断U盘路径是否存在;
#存在则生成MLO、拷贝,不存在则提示报错
if [ ! -d “
m
y
P
a
t
h
"
]
;
t
h
e
n
e
c
h
o
−
e
"
myPath" ];then echo -e "
myPath"];thenecho−e"{RED_COLOR}Check USB Disk!${RES}”
else
creat_MLO
fi
sync
exit
{% endcodeblock %}