⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lib.c

📁 本人经过实验的可以再LPC2214上跑起来的ucos-ii。
💻 C
字号:


#include "config.h"

void GPIOOutputMode(uint8 GPIOx, uint32 GPIOPins)
{
    //IOxDIR = GPIOPins;	1--Output;	0--Input
    //0xE0028008:IO0DIR的入口地址	--方向控制寄存器
    (*((volatile unsigned long*)(0xE0028008 + 0x10 * GPIOx))) |= GPIOPins;
}

void GPIOInputMode(uint8 GPIOx, uint32 GPIOPins)
{
    //IOxDIR = GPIOPins;	1--Output;	0--Input
    //0xE0028008:IO0DIR的入口地址	--方向控制寄存器
    (*((volatile unsigned long*)(0xE0028008 + 0x10 * GPIOx))) &= ~GPIOPins;
}

void GPIOSetBits(uint8 GPIOx, uint32 GPIOPins)
{
    //IOxSET = GPIOPins;
    //0xE0028004:IO0SET的入口地址	--置位寄存器
    (*((volatile unsigned long*)(0xE0028004 + 0x10 * GPIOx))) = GPIOPins;

}

void GPIOResetBits(uint8 GPIOx, uint32 GPIOPins)
{
    //IOxCLR = GPIOPins;
    //0xE002800C:IO0CLR的入口地址	--复位寄存器
    (*((volatile unsigned long*)(0xE002800C + 0x10 * GPIOx))) = GPIOPins;

}

//9-8日,下面这几个函数还没有经过测试

uint8 GPIOReadPin(uint8 GPIOx, uint32 GPIOPin)
{
    //0xE0028000:IO0PIN的入口地址	--复位寄存器
    return ((*((volatile unsigned long*)(0xE0028000 + 0x10 * GPIOx))) &GPIOPin) ? 1 : 0;
}

uint32 GPIOReadPort(uint8 GPIOx)
{
    //0xE0028000:IO0PIN的入口地址	--复位寄存器
    return (*((volatile unsigned long*)(0xE0028000 + 0x10 * GPIOx)));
}

void UARTxInit(uint8 UARTx, uint32 baud, UARTMODE set)
{
    uint32 bak;
    /*设置串行口波特率*/
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) |= DIVACCESSENABLE;
    bak = (Fpclk >> 4) / baud;
    //0xE000C00C	--U0DLM
    (*((volatile unsigned char*)(0xE000C004 + UARTx * 0x4000))) = bak >> 8;
    //0xE000C00C	--U0DLL
    (*((volatile unsigned char*)(0xE000C000 + UARTx * 0x4000))) = (bak &0x00ff);
    bak = set.datab - 5; //设置子长度
    if (2 == set.stopb)
    {
        bak |= 0x04; //判断是否为2位停止位
    }
    if (0 != set.parity)
    {
        set.parity = set.parity - 1;
        bak |= 0x08;
    }
    bak |= (set.parity << 4);
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) = bak;
}

void UARTxBaudSet(uint8 UARTx, uint32 BAUDRATE)
{

    uint16 Fdiv;
    //UARTx UxLCR控制寄存器--使能除数寄存器访问
    //0xE000C00C 	--U0LCR
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) |= DIVACCESSENABLE;
    //Fpclk为VPB时钟频率,可以位CCO频率的1~4倍
    Fdiv = (Fpclk / 16) / BAUDRATE;
    //0xE000C00C	--U0DLM
    (*((volatile unsigned char*)(0xE000C004 + UARTx * 0x4000))) = Fdiv >> 8;
    //0xE000C00C	--U0DLL
    (*((volatile unsigned char*)(0xE000C000 + UARTx * 0x4000))) = (Fdiv &0x00ff);
    //0xE000C00C 	--UxLCR	--禁止访问除数控制寄存器
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) &= ~DIVACCESSENABLE;


}

void UARTxBitsSet(uint8 UARTx, uint8 Bits)
{
    //0xE000C00C 	--U0LCR
    //先将低位全部置0
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) &= ~0x11;
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) |= Bits;
}

//默认设置:8bits | 1 stop bits | no parity check | baud = 115200
void UARTxDefInit(uint8 UARTx)
{
    uint16 Fdiv;
    uint32 bak = 0;
    //UARTx UxLCR控制寄存器--使能除数寄存器访问
    //0xE000C00C 	--U0LCR
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) |= DIVACCESSENABLE;
    //Fpclk为VPB时钟频率,可以位CCO频率的1~4倍
    Fdiv = (Fpclk / 16) / BPS_9600;
    //0xE000C00C	--U0DLM
    (*((volatile unsigned char*)(0xE000C004 + UARTx * 0x4000))) = Fdiv >> 8;
    //0xE000C00C	--U0DLL
    (*((volatile unsigned char*)(0xE000C000 + UARTx * 0x4000))) = (Fdiv &0x00ff);
    //0xE000C00C 	--UxLCR	--禁止访问除数控制寄存器
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) &= ~DIVACCESSDISABLE;
    bak |= BITS_8;
    bak |= STOPBITS_1;
    bak |= PARITYDISABLE;
    (*((volatile unsigned char*)(0xE000C00C + UARTx * 0x4000))) = bak;

}

void UARTxEnable(uint8 UARTx)
{
    //将功能选择位UARTx所需要的引脚设为第二功能
    //(UART0:PINSEL0[1:0 & 3:2])
    //(UART1:PINSEL0[17:16 & 19:18])
    PINSEL0 |= (0x05 << (16 *UARTx));
}

void UARTxDisable(uint8 UARTx)
{
    //将PINSEL0 的0~3位全部置0
    PINSEL0 &= ~(0x0f << (16 *UARTx));
}

void UARTxSendByte(uint8 UARTx, uint8 data)
{
    //发送数据0xE000C000----U0THR--发送保持寄存器--Tx FIFO的最高字节
    (*((volatile unsigned char*)(0xE000C000 + UARTx * 0x4000))) = data;
    //等待数据发送完毕0xE000C014----U0LSR--[5]为线状态寄存器的U0THR的状态
    //THR位为空时,此位置位,THR写操作清零该位
    while ((*((volatile unsigned char*)(0xE000C014 + UARTx * 0x4000))) &0x20 == 0)
    {
        //等待数据发送完毕
    }
}

void UARTxSendStr(uint8 UARTx, uint8 const *str)
{
    while (*str != '\0')
    {
        UARTxSendByte(UARTx,  *str++);
    }
}

void UARTxSendBufer(uint8 UARTx, uint8 data[8]) //经过测试
{
    uint8 i;
    for (i = 0; i < 8; i++)
    {
        UARTxSendByte(UARTx, data[i]);
    }
    while ((*((volatile unsigned char*)(0xE000C014 + UARTx * 0x4000))) &0x40 == 0)
        ;
}

void UARTxFIFOSendByte(uint8 UARTx, uint8 data)
{
    //发送数据0xE000C000----U0THR--发送保持寄存器--Tx FIFO的最高字节
    (*((volatile unsigned char*)(0xE000C000 + UARTx * 0x4000))) = data;
}

//目前只能处理uart0中断
void UARTxINTEnable(uint8 UARTx, uint8 CTRLx, uint32 irq_addr)
{
    //0xE000C004--U0IER[0] --使能Rx数据可用中断DLAB=0
    (*((volatile unsigned char*)(0xE000C004 + UARTx * 0x4000))) |= 0x01;
    //(SPI0, I2C, UART1 和UART0 为IRQ => bit10, bit9, bit7 和bit6=0)
    VICIntSelect &= (~(1 << 6));
    //设置UART0所在的通道为IRQ中断//0x00000000;设置所有通道为IRQ中断//&= (~(1 << 6)); //bit6 = 0
    //VICVectCntl0 = 0x20 | UART0IntID;		//将UARTx中断通道分配到IRQ slot 0, 即优先级最高
    (*((volatile unsigned long*)(0xFFFFF200 + CTRLx * 4))) = 0x20 | (UART0IntID + CTRLx);
    //VICIntEnable |= (1 << 6); //使能UART0中断
    //VICVectAddr0 = irq_addr;	
    (*((volatile unsigned long*)(0xFFFFF100 + CTRLx * 4))) = irq_addr;
}


void UARTxINTDisable(uint8 UARTx)
{
    //0xE000C004--U0IER[0] --使能Rx数据可用中断DLAB=0
    (*((volatile unsigned char*)(0xE000C004 + UARTx * 0x4000))) &= ~0x01;

}

void UARTxFIFOEnable(uint8 UARTx, uint8 BytesTrigger)
{
    //0xE000C008----U0FCR
    (*((volatile unsigned char*)(0xE000C008 + UARTx * 0x4000))) = 0x81;
}

void UARTxIntRegister(int addr){

}

void INTEnable(uint32 intSource){


}


void DataAddrBusEnable(void)
{
    PINSEL2 = 0xF9800104; //0xE002c014;//0xE3E017E0;
    /*(
    (0x00 << 0) 		//保留
    | (1 << 2) 			//P1.31:26用作调试端口,即DEBUG模式
    | (0 << 3) 			//P1.25:16用作GPIO
    | (0x00 << 4) 		//P2.7:0=D0:7----P1.0=CS0---P1.1=OE
    //P3.31=BLS0
    | (0 << 6) 			//使能P3.29
    | (0 << 7) 			//使能P3.28
    | (1 << 8) 			//使能WE
    | (0x00 << 9)		//保留
    | (0 << 11) 		//使能P3.26
    | (0 << 12) 		//保留
    | (0 << 13) 		//使能P3.23
    | (0x00 << 14)		//使能P3.25
    | (0x00 << 16) 		//使能P3.24
    | (0x00 << 18) 		//保留
    | (0 << 20) 		//使能P2.29:28
    | (0 << 21)			//使能P2.30
    | (0 << 22) 		//使能P2.31
    | (1 << 23)  		//A0用作地址线
    | (1 < 24) 			//A1用作地址线
    | (0x100 << 25) 	//A11:2为地址线
    | (0x1111 << 28)
    );*/
}

#define resetWR() GPIOResetBits(WR_PORT, WR)
#define setWR() GPIOSetBits(WR_PORT, WR)
#define setRD() GPIOSetBits(RD_PORT, RD)
#define resetRD() GPIOResetBits(RD_PORT, RD)
void writeSpc3(uint32 addr, uint8 data)
{
    //采用的是绝对地址访问的方式
    /*
    volatile uint8 *ip;
    unsigned char i = 100;
    resetWR();
    ip = GetAddr(addr);	
    ip[0] = data;
    while(i --);	//延时
    setWR();
     */
    //9-22日修改,将写数据更改为完全按照老大的时序来读写
    /*步骤:
    1.先将地址线及WR脚设为输出模式
    2.设置VPC3为读无效模式(XRD = 1)
    3.XWR = 1
    4.向地址线上输出数据
    5.设置数据线为输出数据IO
    6.送出数据
    7.XWR=0,触发VPC3的XREADY信号
    8.检查XREADY信号,直到变低为止
    9.产生上升沿,触发VPC3接受数据
     */
    GPIOOutputMode(WR_PORT, WR);
    GPIOOutputMode(RD_PORT, RD);
    GPIOOutputMode(VPC3ADDR_PORT, VPC3ADDR);
    GPIOOutputMode(VPC3DATA_PORT, VPC3DATA);
    GPIOInputMode(XREADY_PORT, XREADY);
    setRD();
    setWR();
    {
        //输出地址【有待优化,先进行测试】
        uint16 addr_bit;
        for (addr_bit = 0; addr_bit < 16; addr_bit++)
        {
            if (addr &(1 << addr_bit))
            {
                GPIOSetBits(VPC3ADDR_PORT, 1 << addr_bit);
            }
            else
            {
                GPIOResetBits(VPC3ADDR_PORT, 1 << addr_bit);
            }
        }
    }
    {
        //输出数据【有待优化,先进行测试】
        uint16 data_bit;
        for (data_bit = 0; data_bit < 8; data_bit++)
        {
            if (data &(1 << data_bit))
            {
                GPIOSetBits(VPC3DATA_PORT, 1 << data_bit);
            }
            else
            {
                GPIOResetBits(VPC3DATA_PORT, 1 << data_bit);
            }
        }
    }
    resetWR();
    while ((GPIOReadPin(XREADY_PORT, XREADY)))
        ;
    setWR();
}

uint8 readSpc3(uint32 addr)
{
    //采用的是绝对地址访问的方式
    /*
    uint8 result;
    volatile uint8 *ip;
    uint16 i = 500;
    resetRD();
    ip = GetAddr(addr);	
    result = ip[0];
    while(i --);	//延时
    setRD();
    return ip[0];
     */
    //9-22日修改,将写数据更改为完全按照老大的时序来读写
    /*步骤:
    1.设置XRD为读使能输出IO
    2.XRD=1
    3.设置VPC3为写无效状态(XWR=1)
    4.设置数据口为数据输入IO
    5.向地址线输出地址
    6.XRD=0,产生下降沿,触发VPC3的XREADY信号
    7.检查XREADY信号,直到XREADY变为低为止
    8.读取数据
    9.XRD=1,产生上升沿,触发SPC3的XREADY信号
    10.将数据返回
     */
    uint8 result = 0x00;
    GPIOOutputMode(WR_PORT, WR);
    GPIOOutputMode(RD_PORT, RD);
    GPIOOutputMode(VPC3ADDR_PORT, VPC3ADDR);
    GPIOInputMode(VPC3DATA_PORT, VPC3DATA);
    GPIOInputMode(XREADY_PORT, XREADY);
    setRD();
    setWR();
    {
        //输出地址【有待优化,先进行测试】
        uint16 addr_bit;
        for (addr_bit = 0; addr_bit < 16; addr_bit++)
        {
            if (addr &(1 << addr_bit))
            {
                GPIOSetBits(VPC3ADDR_PORT, 1 << addr_bit);
            }
            else
            {
                GPIOResetBits(VPC3ADDR_PORT, 1 << addr_bit);
            }
        }
    }
    resetRD();
    while ((GPIOReadPin(XREADY_PORT, XREADY)))
        ;
    result = GPIOReadPort(VPC3DATA_PORT) &0xff;
    return result;
}

void SPC3Reset(void)
{
    GPIOOutputMode(RST_PORT, RST);
    GPIOSetBits(RST_PORT, RST); //将RST引脚拉高
    //VPC3+ requires a minimum reset phase of 100 ns at power-on.
    {
        unsigned char i = 100;
        while (i--)
            ;
    }
    GPIOResetBits(RST_PORT, RST); //将RST引脚置低
}
/*在os_cpu_c.c中已经定义过了
void SWI_Exception(int SWI_Num, int *Regs)
{

    switch (SWI_Num)
    {
        //case 0x00:                    //任务切换函数OS_TASK_SW,参考os_cpu_s.s文件     /
        //    break;
        //case 0x01:                    // 启动任务函数OSStartHighRdy,参考os_cpu_s.s文件 /
        //    break;
        case 0x02:
            // 关中断函数OS_ENTER_CRITICAL(),参考os_cpu.h文件 
            __asm
            {
                MRS R0, SPSR 
                ORR R0, R0,#NoInt
                MSR SPSR_c, R0
            }
            break;
        case 0x03:
            //开中断函数OS_EXIT_CRITICAL(),参考os_cpu.h文件 
            __asm
            {
                MRS R0, SPSR 
                BIC R0, R0,# NoInt
                MSR SPSR_c, R0
            }

            break;

        default:
            break;
    }
}
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -