📄 main.c
字号:
// 基于《Stellaris外设驱动库》的SSI例程:通过75HC595扫描8位共阴式动态数码管
// 包含必要的头文件
#include <hw_types.h>
#include <hw_memmap.h>
#include <hw_ints.h>
#include <hw_sysctl.h>
#include <hw_gpio.h>
#include <hw_timer.h>
#include <hw_ssi.h>
#include <interrupt.h>
#include <sysctl.h>
#include <gpio.h>
#include <timer.h>
#include <ssi.h>
#include "LM3S1138_PinMap.H"
// 将较长的标识符定义为较短的形式
#define SysCtlPeriEnable SysCtlPeripheralEnable
#define SysCtlPeriDisable SysCtlPeripheralDisable
#define GPIOPinTypeIn GPIOPinTypeGPIOInput
#define GPIOPinTypeOut GPIOPinTypeGPIOOutput
// 定义按键
#define KEY_PORT SYSCTL_PERIPH_GPIOG
#define KEY_PIN GPIO_PORTG_BASE , GPIO_PIN_5
#define KeyGet() GPIOPinRead(KEY_PIN)
// 防止JTAG失效
void jtagWait(void)
{
SysCtlPeriEnable(KEY_PORT); // 使能按键所在的GPIO端口
GPIOPinTypeIn(KEY_PIN); // 设置按键所在管脚为输入
if ( KeyGet() == 0x00 ) // 如果有键按下,则进入
{
for (;;); // 死循环,以等待JTAG连接
}
SysCtlPeriDisable(KEY_PORT); // 禁止按键所在的GPIO端口
}
// 延时
void Delay(unsigned long ulVal)
{
while ( --ulVal != 0 );
}
// SSI初始化
void ssiInit(void)
{
unsigned long ulBitRate = SysCtlClockGet() / 10;
SysCtlPeriEnable(SSI0CLK_PERIPH); // 使能SSI模块所在的GPIO端口
SysCtlPeriEnable(SYSCTL_PERIPH_SSI); // 使能SSI模块
GPIOPinTypeSSI(SSI0CLK_PORT , SSI0CLK_PIN | // 将相关GPIO设置为SSI功能
SSI0FSS_PIN |
SSI0RX_PIN |
SSI0TX_PIN);
SSIConfig(SSI_BASE , // 配置SSI模块
SSI_FRF_MOTO_MODE_0 , // Freescale格式,模式0
SSI_MODE_MASTER , // 主模式
ulBitRate , // 设置位速率
16); // 设置数据宽度
SSIEnable(SSI_BASE); // 使能SSI收发
}
// 定时器初始化
void timerInit(void)
{
unsigned long ulClock = SysCtlClockGet() / (60 * 8); // 扫描速度在60Hz以上才不会感到闪烁
SysCtlPeriEnable(SYSCTL_PERIPH_TIMER0); // 使能定时器模块
TimerConfigure(TIMER0_BASE , TIMER_CFG_32_BIT_PER); // 配置为32位周期定时器
TimerLoadSet(TIMER0_BASE , TIMER_A , ulClock); // 设置定时器初值
TimerIntEnable(TIMER0_BASE , TIMER_TIMA_TIMEOUT); // 使能定时器超时中断
IntEnable(INT_TIMER0A); // 使能定时器中断
IntMasterEnable(); // 使能处理器中断
TimerEnable(TIMER0_BASE , TIMER_A); // 使能定时器计数
}
// 定义显示缓冲区
unsigned char dispBuf[8];
// 显示初始化
void dispInit(void)
{
unsigned short i;
for ( i = 0; i < 8; i++ )
{
dispBuf[i] = 0x00;
}
ssiInit();
timerInit();
}
// 显示一个数字
void dispDataPut(unsigned char ucX , unsigned char ucData)
{
dispBuf[ucX & 0x07] = ucData;
}
// 定时器的中断服务函数
void Timer0A_ISR(void)
{
const unsigned char SegTab[16] = // 定义数码管段选数据
{
0x3F , 0x06 , 0x5B , 0x4F , 0x66 , 0x6D , 0x7D , 0x07 ,
0x7F , 0x6F , 0x77 , 0x7C , 0x39 , 0x5E , 0x79 , 0x71
};
const unsigned char DigTab[8] = // 定义数码管位选数据
{
0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80
};
static unsigned char n = 0;
unsigned short t;
TimerIntClear(TIMER0_BASE , TIMER_TIMA_TIMEOUT); // 清除定时器超时中断,重要!
t = DigTab[n] ^ 0xFF; // 获取位选数据
t <<= 8; // 位选数据放在高8位
t |= SegTab[dispBuf[n] & 0x0F]; // 段选数据放在低8位
SSIDataPut(SSI_BASE , t); // 输出数据,共16个有效位
if ( ++n >= 8 )
{
n = 0;
}
}
// 主函数(程序入口)
int main(void)
{
unsigned char i , x;
jtagWait(); // 防止JTAG失效,重要!
SysCtlLDOSet(SYSCTL_LDO_2_50V); // 设置LDO输出电压
SysCtlClockSet(SYSCTL_USE_OSC | // 系统时钟设置,采用主振荡器
SYSCTL_OSC_MAIN |
SYSCTL_XTAL_6MHZ |
SYSCTL_SYSDIV_1);
dispInit(); // 显示初始化
for (;;)
{
for ( i = 0; i < 9; i++ ) // 在数码管上滚动显示0~F
{
for ( x = 0; x < 8; x++ )
{
dispDataPut(x , i+x);
}
Delay(2000 * (6000000UL / 4000));
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -