2、IO口操作寄存器(示例)
#include <AT91SAM7X256.H>
void wait (void) {
unsigned int n;
for (n = 0; n <1843200; n++);
}
int main(void)
{
// *AT91C_PIOB_PER = 1 << 30; //(使能IO口30)AT91C_PIOB_PDR 禁止IO口
*AT91C_PIOB_OER = 1 << 30; //设置IO口30为输出口(*AT91C_PIOB_ODR = 1 << 30;禁止输出口即为设置成输入口)
while(1)
{
*AT91C_PIOB_SODR = 1 << 30; //IO30置位
wait();
*AT91C_PIOB_CODR = 1 << 30; //IO30清零
wait();
}
}
3、以前的lib_at91....里调用子函数的方法
#include <AT91SAM7X256.H>
#include <lib_AT91SAM7X256.h>
void wait (void)
{
unsigned int n;
for (n = 0; n <1843200; n++);
}
int main (void) //从12行到26行这种函数在 lib_AT91SAM7X256.h库文件里面,编程中此种方式与操作寄存器那种常用?
{
AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_PIOB); //IO口使能
AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB27); //设这输出口
AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB28);
AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB29);
AT91F_PIO_CfgOutput(AT91C_BASE_PIOB, AT91C_PIO_PB30);
AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB30); //某一位,置位
AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB29); //某一位,置位
AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB28); //某一位,置位
AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB27); //某一位,置位
while (1) {
AT91F_PIO_ClearOutput(AT91C_BASE_PIOB, AT91C_PIO_PB27); //LED4亮
wait();
AT91F_PIO_SetOutput (AT91C_BASE_PIOB, AT91C_PIO_PB27); //LED4灭
wait();
}
}
4、键盘输入
#include <AT91SAM7X256.H>
void wait (void) {
unsigned int n;
for (n = 0; n <1843200; n++);
}
int main(void)
{ unsigned int key_val; //定义一个32位变量
/**********************************************************************************************************/
没有下面两行使能时钟语句的话按键不管用,即读引脚没工作。原因是AT91SAM7X256内部集成了公路管理控制器,用它来控制所有外设的时钟一达到优化功耗的目的。所以只有使能PIO的外围时钟,PIO外设才会工作,才能读入输入管脚的状态,那么为什么PIO作为输出时不需要使能外围时钟呢?我个人认为这与内部外设在数字电路上的实现有关,输出功能只需要组合逻辑电路(不用时钟)就能实现,而输入功能则需要用到时序逻辑电路(需要时钟)才能实现。
因此,必须在main()函数的开头增加以下两条时钟使能的语句
*AT91C_PMC_SCER = AT91C_CKGR_MOSCEN;//使能系统时钟进村器的处理时钟
*AT91C_PMC_PCER = 1 <<AT91C_ID_PIOA;//使能PIOA外围时钟
/************************************************************************************************************/
*AT91C_PIOB_PER = 1 << 30; //使能PIOB30
*AT91C_PIOA_PER = 1 << 29; //使能PIOA29
*AT91C_PIOB_OER = 1 << 30; //设置PIOB输出使能
*AT91C_PIOA_ODR = 1 << 29; //禁止PIOA29输出使能(输入使能)
while(1)
{
key_val = *AT91C_PIOA_PDSR; //读取管脚电平
if(key_val & (1 << 29)) //判断输入引脚PIOA29的电平
{
*AT91C_PIOB_SODR = 1 <<30; //把电平反映给PIOB输出给LED
}
else
{
*AT91C_PIOB_CODR = 1 <<30; //把电平反映给PIOB输出给LED
}
}
}
5 两个判断语句
在这里顺便对条件编译(#ifdef, #else, #endif, #if等)进行说明。以下分3种情况:
1. 情况1:
#ifdef _XXXX
...程序段1...
#else
...程序段2...
#endif
这表明如果标识符_XXXX已被#define命令定义过则对程序段1进行编译;否则对程序段2进行编译。
例:
#define NUM
.............
.............
.............
#ifdef NUM
printf("之前NUM有过定义啦! \n");
#else
printf("之前NUM没有过定义! \n");
#endif
}
如果程序开头有#define NUM这行,即NUM有定义,碰到下面#ifdef NUM的时候,当然执行第一个printf。否则第二个printf将被执行。
我认为,用这种,可以很方便的开启/关闭整个程序的某项特定功能。
2:情况2:
#ifndef _XXXX
...程序段1...
#else
...程序段2...
#endif
这里使用了#ifndef,表示的是if not def。当然是和#ifdef相反的状况(如果没有定义了标识符_XXXX,那么执行程序段1,否则执行程序段2)。例子就不举了。
3:情况3:
#if 常量
...程序段1...
#else
...程序段2...
#endif
这里表示,如果常量为真(非0,随便什么数字,只要不是0),
就执行程序段1,否则执行程序段2。
如果有#if需要顶格写
6 Keil下生成.bin
C:\Keil\ARM\BIN40\fromelf.exe --bin -o ./bin/1.bin ./1.axf
7 IFB0704 光耦部分
光耦平时输出端与地断开,输出引脚加1阻值较大的上拉电阻,输出1;输入端有电流,发光时,输出端与地连接,输出被拉低,输出0
8、232串口。at91sam7x256
9 IFB的48芯片5,7脚->BB->J7的1脚->接标准串口线的2脚(RXD)
AA(6脚)接3脚(TXD)
10、由232的usart0端口改为485usart1端口,可以写数据,
不能进入中断读数据回显,以后再调试
文章评论(0条评论)
登录后参与讨论