📄 ssi_send_reg.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzhou ZHIYUAN electronics Co.,LTD.
**
** http://www.embedtools.com
**
**--------------File Info-------------------------------------------------------------------------------
** File Name: ssi_send_reg.c
** Last modified Date: 2006-11-15
** Last Version: v1.0
** Description: 通过 SSI 接口循环向外输出 0~F 的字模,74HC595 接收到 SSI 信号以后
** 在7段数码管上显示相应的字符。
**
**------------------------------------------------------------------------------------------------------
** Created By: Yang Li
** Created date: 2006-11-15
** Version: v1.0
** Descriptions:
**
**------------------------------------------------------------------------------------------------------
** Modified by: Pan Yi Fei
** Modified date: 2007-04-28
** Version: v1.1
** Description: 增加了unsigned long SysCtlClockGet(void) 函数
**
********************************************************************************************************/
#define HWREG(x) (*((volatile unsigned long *)(x)))
#define SYSCTL_PERIPH_SSI 0x10000010 // SSI 在系统控制器中的地址
#define SYSCTL_PERIPH_GPIOA 0x20000001 // GPIO A 在系统控制器中的地址
#define SYSCTL_RCGC1 0x400fe104 // 运行模式时钟门控寄存器 1
#define SYSCTL_RCGC2 0x400fe108 // 运行模式时钟门控寄存器 2
#define SYSCTL_RCC 0x400fe060 // 运行-模式时钟配置寄存器
#define SYSCTL_PLLCFG 0x400fe064 // XTAL-PLL转换寄存器
#define SYSCTL_RCC_XTAL_MASK 0x000003C0 // Crystal attached to main osc
#define SYSCTL_RCC_OSCSRC_MASK 0x00000030 // 振荡器相关的位
#define SYSCTL_RCC_OSCSRC_MAIN 0x00000000 // 使用主振荡器
#define SYSCTL_RCC_OSCSRC_INT 0x00000010 // 使用内部振荡器
#define SYSCTL_RCC_OSCSRC_INT4 0x00000020 // 内部振荡器 / 4
#define SYSCTL_RCC_XTAL_SHIFT 6 // 移位到振荡器的相关位
#define SYSCTL_RCC_XTAL_3_57MHZ 0x00000100 // 使用3.579545MHz 晶振
#define SYSCTL_RCC_BYPASS 0x00000800 // PLL旁路
#define SYSCTL_RCC_USE_SYSDIV 0x00400000 // 使用系统时钟除数
#define SYSCTL_RCC_SYSDIV_MASK 0x07800000 // 系统时钟除数
#define SYSCTL_RCC_SYSDIV_SHIFT 23 // 移位到系统时钟除数的相关位
#define SYSCTL_PLLCFG_OD_MASK 0x0000C000 // 输出除数
#define SYSCTL_PLLCFG_OD_1 0x00000000 // OD值 1
#define SYSCTL_PLLCFG_OD_2 0x00004000 // 2
#define SYSCTL_PLLCFG_OD_4 0x00008000 // 4
#define SYSCTL_PLLCFG_F_MASK 0x00003FE0 // F输入值
#define SYSCTL_PLLCFG_R_MASK 0x0000001F // R输入值
#define SYSCTL_PLLCFG_F_SHIFT 5 // 移位到F的相关位
#define SYSCTL_PLLCFG_R_SHIFT 0 // 移位到R的相关位
#define SSI_BASE 0x40008000 // SSI 基地址
#define SSI_O_CR0 0x00000000 // SSI 控制寄存器0
#define SSI_O_CR1 0x00000004 // SSI 控制寄存器1
#define SSI_O_DR 0x00000008 // SSI 数据寄存器
#define SSI_O_SR 0x0000000C // SSI 状态寄存器
#define SSI_O_CPSR 0x00000010 // SSI 时钟分频寄存器
#define SSI_MODE_MASTER 0x00000000 // SSI 主模式
#define SSI_FRF_MOTO_MODE_0 0x00000000 // Moto 帧格式,极性0,相位0
#define SSI_CR0_FRF_MASK 0x00000030 // 帧格式屏蔽
#define SSI_CR1_SSE 0x00000002 // 同步端口使能
#define SSI_SR_TNF 0x00000002 // TX FIFO未满
#define GPIO_PORTA_BASE 0x40004000 // GPIO A 端口基地址
#define GPIO_PIN_2 0x00000004 // GPIO 引脚 2
#define GPIO_PIN_3 0x00000008 // GPIO 引脚 3
#define GPIO_PIN_4 0x00000010 // GPIO 引脚 4
#define GPIO_PIN_5 0x00000020 // GPIO 引脚 5
#define GPIO_O_AFSEL 0x00000420 // 模式控制选择寄存器
#define BitRate 115200 // 设定波特率
#define DataWidth 8 // 设定数据宽度
// 此表为7段数码管显示0~F的字模
unsigned char DISP_TAB[16] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};
const unsigned long g_pulXtals[] =
{
3579545,
3686400,
4000000,
4096000,
4915200,
5000000,
5120000,
6000000,
6144000,
7372800,
8000000,
8192000
};
//-----------------------------------------------------------------------------
// 函数原形:void delay(unsigned long d)
// 功能描述:延时数量为 d 个指令周期。
// 参数说明:unsigned long d,将要延时的时间数。
// 返回值:无
//-----------------------------------------------------------------------------
void delay(unsigned long d)
{
for(;d;d--);
}
//
//-----------------------------------------------------------------------------
// 函数原形:unsigned long SysCtlClockGet(void)
// 功能描述:获取处理器时钟速率。
// 参数说明:无。
// 返回值:时钟速率
//-----------------------------------------------------------------------------
unsigned long SysCtlClockGet(void)
{
unsigned long ulRCC, ulPLL, ulClk;
// 读 RCC.
ulRCC = HWREG(SYSCTL_RCC);
// 获取基本时钟速率
switch(ulRCC & SYSCTL_RCC_OSCSRC_MASK)
{
// 主时钟模式
case SYSCTL_RCC_OSCSRC_MAIN:
{
ulClk = g_pulXtals[((ulRCC & SYSCTL_RCC_XTAL_MASK) >>
SYSCTL_RCC_XTAL_SHIFT) -
(SYSCTL_RCC_XTAL_3_57MHZ >>
SYSCTL_RCC_XTAL_SHIFT)];
break;
}
// 内部时钟
case SYSCTL_RCC_OSCSRC_INT:
{
ulClk = 15000000;
break;
}
// 内部时钟的/4
case SYSCTL_RCC_OSCSRC_INT4:
{
ulClk = 15000000 / 4;
break;
}
default:
{
return(0);
}
}
// 使用PLL倍频的情况
if(!(ulRCC & SYSCTL_RCC_BYPASS))
{
// 获取PLL的配置值
ulPLL = HWREG(SYSCTL_PLLCFG);
ulClk = ((ulClk * (((ulPLL & SYSCTL_PLLCFG_F_MASK) >>
SYSCTL_PLLCFG_F_SHIFT) + 2)) /
(((ulPLL & SYSCTL_PLLCFG_R_MASK) >>
SYSCTL_PLLCFG_R_SHIFT) + 2));
// 2分频
if(ulPLL & SYSCTL_PLLCFG_OD_2)
{
ulClk /= 2;
}
// 4分频
if(ulPLL & SYSCTL_PLLCFG_OD_4)
{
ulClk /= 4;
}
}
if(ulRCC & SYSCTL_RCC_USE_SYSDIV)
{
// 调整时钟
ulClk /= ((ulRCC & SYSCTL_RCC_SYSDIV_MASK) >>
SYSCTL_RCC_SYSDIV_SHIFT) + 1;
}
return(ulClk);
}
//-----------------------------------------------------------------------------
// 函数原形:int main(void)
// 功能描述:主函数
// 参数说明:无
// 返回值:0
//-----------------------------------------------------------------------------
int main(void)
{
// 设置 SSI 时钟预分频器。
unsigned long ulMaxBitRate;
unsigned long ulPreDiv;
unsigned long ulSCR;
unsigned long ulClock;
unsigned char i;
// 使能 SSI
HWREG(SYSCTL_RCGC1) |= SYSCTL_PERIPH_SSI & 0x0fffffff;
// 使能 GPIO A 口
HWREG(SYSCTL_RCGC2) |= SYSCTL_PERIPH_GPIOA & 0x0fffffff;
delay(6);
// 配置 SSI 为主模式
HWREG(SSI_BASE + SSI_O_CR1) = 0;
ulClock = SysCtlClockGet();
ulMaxBitRate = ulClock / BitRate;
ulPreDiv = 0;
do
{
ulPreDiv += 2;
ulSCR = (ulMaxBitRate / ulPreDiv) - 1;
}
while(ulSCR > 255);
HWREG(SSI_BASE + SSI_O_CPSR) = ulPreDiv;
// 设置 SSI 传输协议和时钟速率。
HWREG(SSI_BASE + SSI_O_CR0) = ((ulSCR << 8) | (SSI_FRF_MOTO_MODE_0 << 6) |
(SSI_FRF_MOTO_MODE_0 & SSI_CR0_FRF_MASK) | (DataWidth - 1));
// 使能 SSI
HWREG(SSI_BASE + SSI_O_CR1) |= SSI_CR1_SSE;
// 设定 GPIO A 2~5 引脚为使用外设功能
HWREG(GPIO_PORTA_BASE + GPIO_O_AFSEL) |= (GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5);
while (1)
{
// 循环输出 0~F 的字模
for (i=0; i<16; i++)
{
// 等待直到有空间。
while (!(HWREG(SSI_BASE + SSI_O_SR) & SSI_SR_TNF))
{
}
// 向SSI写数据。
HWREG(SSI_BASE + SSI_O_DR) = DISP_TAB[i];
// 输出后延时一段时间
delay(600000);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -