Cortex-K60自学笔记(一)

底层函数编写(gpio,uart)

写这篇博客算是自我激励吧,一直以来都没有说有特别大的决心去做一件事,想通过这种方式去让自己有所坚持,有所进步吧。我也觉得面对一件事,要么就不要开始,要么就尽己所能去做好。

gpio.h

#ifndef GPIO_H
#define GPIO_H


typedef struct
{
uint32  PDOR  ;		//端口数据输出寄存器
uint32  PSOR  ;		//端口数据置一寄存器
uint32  PCOR  ;		//端口数据清零寄存器
uint32  PTOR  ;     //端口数据反转寄存器
uint32  PDIR  ;  	//端口数据输入寄存器
uint32  PDDR  ;     //端口数据方向寄存器
}volatile *GPIO_MemMapPtr;


typedef struct PORT_MemMap
{
uint32 PCR[32];		//32个引脚
uint32 GPCLR;	 
uint32 GPCHR;
uint8 RESERVED_0[24];
uint32 ISFR;		//中断配置寄存器
}volatile *PORT_MemMapPtr;
//这里首先定义了两个结构体变量,一个是port register,一个是gpio register,印象特别深的是关于两者的差别,我的理解是port register 初始化通用的一些端口设置,gpio register用于初始化gpio的一些设置,比如说中断必须在port里面设置。

//这里的GPIO_Type *是和GPIO_MemMapPtr等价的
#define PTA                                      ((GPIO_Type *)PTA_BASE)
/** Peripheral PTB base address */
#define PTB_BASE                                 (0x400FF040u)
/** Peripheral PTB base pointer */
#define PTB                                      ((GPIO_Type *)PTB_BASE)
/** Peripheral PTC base address */
#define PTC_BASE                                 (0x400FF080u)
/** Peripheral PTC base pointer */
#define PTC                                      ((GPIO_Type *)PTC_BASE)
/** Peripheral PTD base address */
#define PTD_BASE                                 (0x400FF0C0u)
/** Peripheral PTD base pointer */
#define PTD                                      ((GPIO_Type *)PTD_BASE)
/** Peripheral PTE base address */
#define PTE_BASE                                 (0x400FF100u)
/** Peripheral PTE base pointer */
#define PTE                                      ((GPIO_Type *)PTE_BASE)



#define g_PORTA_BASE_PTR ((PORT_MemMapPtr)0x40049000u)
#define g_PORTB_BASE_PTR ((PORT_MemMapPtr)0x4004A000u)
#define g_PORTC_BASE_PTR ((PORT_MemMapPtr)0x4004B000u)
#define g_PORTD_BASE_PTR ((PORT_MemMapPtr)0x4004C000u)
#define g_PORTE_BASE_PTR ((PORT_MemMapPtr)0x4004D000u)

#define g_PTA_BASE_PTR ((GPIO_MemMapPtr)0x40049000u)
#define g_PTB_BASE_PTR ((GPIO_MemMapPtr)0x4004A000u)
#define g_PTC_BASE_PTR ((GPIO_MemMapPtr)0x4004B000u)
#define g_PTD_BASE_PTR ((GPIO_MemMapPtr)0x4004C000u)
#define g_PTE_BASE_PTR ((GPIO_MemMapPtr)0x4004D000u)


#define g_GPIO_PDOR_REG(base)   ((base)->PDOR)
#define g_GPIO_PSOR_REG(base)   ((base)->PSOR)
#define g_GPIO_PCOR_REG(base)   ((base)->PCOR)
#define g_GPIO_PTOR_REG(base)   ((base)->PTOR)
#define g_GPIO_PDIR_REG(base)   ((base)->PDIR)
#define g_GPIO_PDDR_REG(base)   ((base)->PDDR)
#define g_PORT_PCR_REG(port_ptr,port_bit) ((port_ptr)->PCR[port_bit])
#define g_PORT_ISFR_REG(base) ((base)->ISFR)


#define OUTPUT_L        0       
#define OUTPUT_H        1       
#define INPUT_PULL_DOWN (0|PORT_PCR_PE_MASK)                      
#define INPUT_PULL_UP   (PORT_PCR_PS_MASK|PORT_PCR_PE_MASK)       

#define PORT_PCR_MUX(x)     (((uint32_t)(((uint32_t)(x))<<PORT_PCR_MUX_SHIFT))&PORT_PCR_MUX_MASK)

//typedef void (*GPIO_ISR_CALLBACK)(void);

//GPIO_ISR_CALLBACK GPIO_ISR[5];

uint8 g_LPLD_GPIO_Init(GPIO_Type * port ,uint8 pin,uint8 dir ,uint8 data);

void g_LPLD_GPIO_Set(GPIO_Type *port,uint8 pin,uint8 data);

uint32 g_LPLD_GPIO_Get(GPIO_Type *port,uint8 pin);

PORT_MemMapPtr ptToPort(GPIO_Type * port);

void delay_ms(long int time);

void gpio_turn (GPIO_Type * port,uint8 pin);

typedef void (*GPIO_ISR_CALLBACK)(void);

void port_isr(void);



#endif

对于头文件的梗,最想说的是关于拉普兰德v3库很多变量都变了,然后补各种变量,函数。但慢慢的写底层也看到的一些函数了解到了一些单片机原理,关于寄存器, 最直接的感受便是通过定位改变相应位的数值实现对零件的控制。

gpio.c



#include "common.h"
#include "gpio.h"



PORT_MemMapPtr ptToPort(GPIO_Type * port)
{
  if(port==PTA)
    return g_PORTA_BASE_PTR;
  else if(port==PTB)
    return g_PORTB_BASE_PTR;
  else if(port==PTC)
    return g_PORTC_BASE_PTR;
  else if(port==PTD)
    return g_PORTD_BASE_PTR;
  else if(port==PTE)
    return g_PORTE_BASE_PTR;
  else 
    return 0;
}


uint8 g_LPLD_GPIO_Init(GPIO_Type *port,uint8 pin,uint8 dir ,uint8 data)
{
  GPIO_Type *gpio_ptr=port;
  PORT_MemMapPtr port_ptr=ptToPort(port);
  ASSERT(port<PTE);
  ASSERT(pin<=31);
  ASSERT(dir<=1);
  ASSERT(data<=1);
  g_PORT_PCR_REG(port_ptr,pin)=PORT_PCR_MUX(1);		//设置端口复用
  

  GPIO_ISR_CALLBACK isr_func = port_isr;  	//关于这里首先是指定了中断函数
  enable_irq((IRQn_Type)(0 + PORTA_IRQn));	//接着是启用中断函数
  
  
  if(dir==DIR_OUTPUT)
  {
    g_GPIO_PDDR_REG(gpio_ptr)|=0x1u<<pin;
    if(data==OUTPUT_H)
      g_GPIO_PSOR_REG(gpio_ptr)=0x1u<<pin;
    else
      g_GPIO_PCOR_REG(gpio_ptr)=0x1u<<pin; 
  }
   
  else
  {
    g_GPIO_PDDR_REG(gpio_ptr)&=~(0x1u<<pin);
    if(data==INPUT_PULL_UP)
      g_PORT_PCR_REG(port_ptr,pin)|=PORT_PCR_PE_MASK|PORT_PCR_PS_MASK;
    else if(data==INPUT_PULL_DOWN)
      g_PORT_PCR_REG(port_ptr,pin)=PORT_PCR_PE_MASK;
    else
      g_PORT_PCR_REG(port_ptr,pin)&=~PORT_PCR_PE_MASK;
  }
   //这里其实也可以通过移位&实现对应位置设置
  return 1;
}


     
 void g_LPLD_GPIO_Set(GPIO_Type * port,uint8 pin,uint8 data)
 {
   GPIO_Type *gpio_ptr=port;
   gpio_ptr->PDOR = (gpio_ptr->PDOR & ~(0x01L<<pin)) | (uint32)(data << pin);
 }




 uint32 g_LPLD_GPIO_Get(GPIO_Type * port,uint8 pin)
 {
   GPIO_Type *gpio_ptr=port;
   return gpio_ptr->PDIR>=1?1:0;
 }
//一个简易的延时函数
void delay_ms(long int time)
{
  int i,j;
  for (i = 0; i<1000; i++)
  for(j = 0; j < 1000; j++);
     
}


void gpio_turn (GPIO_Type * port,uint8 pin)
{      
    GPIO_Type *gpio_ptr=port;
    gpio_ptr->PTOR |=  (1 << pin);                                                                                         
}

void port_isr(void)
{
  if(LPLD_GPIO_IsPinxExt(PORTA, GPIO_Pin19))
  {
    //去抖
    delay_ms(10);
    if(PTA19_I==0)
    {
      PTA10_O=0;
      delay_ms(10);delay_ms(10);delay_ms(10);
      delay_ms(10);delay_ms(10);delay_ms(10);
      delay_ms(10);delay_ms(10);delay_ms(10);
    }
    else
    {
    PTA10_O=0;
      delay_ms(10);delay_ms(10);delay_ms(10);
      delay_ms(10);delay_ms(10);delay_ms(10);
      delay_ms(10);delay_ms(10);delay_ms(10);
    }
  } 
}                                                                 
uart.h

#ifndef UART_H
#define UART_H


typedef struct g_UART_MemMapPtr
{
  
  uint8 BDH;                                /**< UART Baud Rate Registers:High, offset: 0x0 */
  uint8 BDL;                                /**< UART Baud Rate Registers: Low, offset: 0x1 */
  uint8 C1;                                 /**< UART Control Register 1, offset: 0x2 */
  uint8 C2;                                 /**< UART Control Register 2, offset: 0x3 */
  uint8 S1;                                 /**< UART Status Register 1, offset: 0x4 */
  uint8 S2;                                 /**< UART Status Register 2, offset: 0x5 */
  uint8 C3;                                 /**< UART Control Register 3, offset: 0x6 */
  uint8 D;                                  /**< UART Data Register, offset: 0x7 */
  uint8 MA1;                                /**< UART Match Address Registers 1, offset: 0x8 */
  uint8 MA2;                                /**< UART Match Address Registers 2, offset: 0x9 */
  uint8 C4;                                 /**< UART Control Register 4, offset: 0xA */
  uint8 C5;                                 /**< UART Control Register 5, offset: 0xB */
  uint8 ED;                                 /**< UART Extended Data Register, offset: 0xC */
  uint8 MODEM;                              /**< UART Modem Register, offset: 0xD */
  uint8 IR;                                 /**< UART Infrared Register, offset: 0xE */
  uint8 RESERVED_0[1];
  uint8 PFIFO;                              /**< UART FIFO Parameters, offset: 0x10 */
  uint8 CFIFO;                              /**< UART FIFO Control Register, offset: 0x11 */
  uint8 SFIFO;                              /**< UART FIFO Status Register, offset: 0x12 */
  uint8 TWFIFO;                             /**< UART FIFO Transmit Watermark, offset: 0x13 */
  uint8 TCFIFO;                             /**< UART FIFO Transmit Count, offset: 0x14 */
  uint8 RWFIFO;                             /**< UART FIFO Receive Watermark, offset: 0x15 */
  uint8 RCFIFO;                             /**< UART FIFO Receive Count, offset: 0x16 */
  uint8 RESERVED_1[1];
  uint8 C7816;                              /**< UART 7816 Control Register, offset: 0x18 */
  uint8 IE7816;                             /**< UART 7816 Interrupt Enable Register, offset: 0x19 */
  uint8 IS7816;                             /**< UART 7816 Interrupt Status Register, offset: 0x1A */
  union
  {                                          /* offset: 0x1B */
    uint8 WP7816_T_TYPE0;                     /**< UART 7816 Wait Parameter Register, offset: 0x1B */
    uint8 WP7816_T_TYPE1;                     /**< UART 7816 Wait Parameter Register, offset: 0x1B */
  };
  uint8 WN7816;                             /**< UART 7816 Wait N Register, offset: 0x1C */
  uint8 WF7816;                             /**< UART 7816 Wait FD Register, offset: 0x1D */
  uint8 ET7816;                             /**< UART 7816 Error Threshold Register, offset: 0x1E */
  uint8 TL7816; 
  
}volatile *g_UART_MemMapPtr;


#ifndef UART0_BASE
#define UART0_BASE                               (0x4006A000u)
/** Peripheral UART0 base pointer */
#define UART0                                    ((g_UART_MemMapPtr)UART0_BASE)
/** Peripheral UART1 base address */
#define UART1_BASE                               (0x4006B000u)
/** Peripheral UART1 base pointer */
#define UART1                                    ((g_UART_MemMapPtr)UART1_BASE)
/** Peripheral UART2 base address */
#define UART2_BASE                               (0x4006C000u)
/** Peripheral UART2 base pointer */
#define UART2                                    ((g_UART_MemMapPtr)UART2_BASE)
/** Peripheral UART3 base address */
#define UART3_BASE                               (0x4006D000u)
/** Peripheral UART3 base pointer */
#define UART3                                    ((g_UART_MemMapPtr)UART3_BASE)
/** Peripheral UART4 base address */
#define UART4_BASE                               (0x400EA000u)
/** Peripheral UART4 base pointer */
#define UART4                                    ((g_UART_MemMapPtr)UART4_BASE)
/** Peripheral UART5 base address */
#define UART5_BASE                               (0x400EB000u)
/** Peripheral UART5 base pointer */
#define UART5                                    ((g_UART_MemMapPtr)UART5_BASE)

#endif

typedef enum UARTn
{
  g_UART0=UART0_BASE,
  g_UART1=UART1_BASE,
  g_UART2=UART2_BASE,
  g_UART3=UART3_BASE,
  g_UART4=UART4_BASE,
  g_UART5=UART5_BASE,
}UARTn;

typedef struct SIM_Type
{
  uint32 SOPT1;                             /**< System Options Register 1, offset: 0x0 */
  uint8 RESERVED_0[4096];
  uint32 SOPT2;                             /**< System Options Register 2, offset: 0x1004 */
  uint8 RESERVED_1[4];
  uint32 SOPT4;                             /**< System Options Register 4, offset: 0x100C */
  uint32 SOPT5;                             /**< System Options Register 5, offset: 0x1010 */
  uint32 SOPT6;                             /**< System Options Register 6, offset: 0x1014 */
  uint32 SOPT7;                             /**< System Options Register 7, offset: 0x1018 */
  uint8 RESERVED_2[8];
  uint32 SDID;                              /**< System Device Identification Register, offset: 0x1024 */
  uint32 SCGC1;                             /**< System Clock Gating Control Register 1, offset: 0x1028 */
  uint32 SCGC2;                             /**< System Clock Gating Control Register 2, offset: 0x102C */
  uint32 SCGC3;                             /**< System Clock Gating Control Register 3, offset: 0x1030 */
  uint32 SCGC4;                             /**< System Clock Gating Control Register 4, offset: 0x1034 */
  uint32 SCGC5;                             /**< System Clock Gating Control Register 5, offset: 0x1038 */
  uint32 SCGC6;                             /**< System Clock Gating Control Register 6, offset: 0x103C */
  uint32 SCGC7;                             /**< System Clock Gating Control Register 7, offset: 0x1040 */
  uint32 CLKDIV1;                           /**< System Clock Divider Register 1, offset: 0x1044 */
  uint32 CLKDIV2;                           /**< System Clock Divider Register 2, offset: 0x1048 */
  uint32 FCFG1;                             /**< Flash Configuration Register 1, offset: 0x104C */
  uint32 FCFG2;                             /**< Flash Configuration Register 2, offset: 0x1050 */
  uint32 UIDH;                              /**< Unique Identification Register High, offset: 0x1054 */
  uint32 UIDMH;                             /**< Unique Identification Register Mid-High, offset: 0x1058 */
  uint32 UIDML;                             /**< Unique Identification Register Mid Low, offset: 0x105C */
  uint32 UIDL;                              /**< Unique Identification Register Low, offset: 0x1060 */
} volatile *g_SIM_Type;

#define SIM_BASE                                 (0x40047000u)
#define SIM                                      ((SIM_Type *)SIM_BASE)
#define SIM_SCGC4_REG(base)                      ((base)->SCG4)
uint32 SCGC4;     
#define SIM_SCGC4                                SIM_SCGC4_REG(SIM_BASE_PTR)


#define UART_C2_REG(base)                        ((base)->C2)
#define UART_C1_REG(base)                        ((base)->C1)
#define UART_BDH_REG(base)                       ((base)->BDH)
#define UART_BDL_REG(base)                       ((base)->BDL)
#define UART_C4_REG(base)                        ((base)->C4)
#define UART_D_REG(base)                         ((base)->D)
#define UART_PFIFO_REG(base)                     ((base)->PFIFO)

void uart_init(UARTn uartn,uint32 baud,uint32 PORT_TX,uint32 PORT_RX);
void uart_send1(UARTn uartn,uint8 ch);
void uart_sendn(UARTn uarrtn,uint16 len,uint8 *buff);
void uart_re1(UARTn uartn,uint8 fp);
void uart_ren(UARTn uarrtn,uint16 len,uint8 *buff);
void uart_enable_re_init(UARTn uartn);
void uart_disable_re_init(UARTn uartn);

#endif
uart.c

#include "common.h"
#include "uart.h"

void uart_init(UARTn uartn,uint32 baud,uint32 PORT_TX,uint32 PORT_RX)
{
     register uint16 sbr,brfa;
     uint8 temp;
     uint32 sysclk;
     
     switch(uartn)
     {
     case g_UART0:
        SCGC4|=SIM_SCGC4_UART0_MASK;  
        
        if(PORT_TX==PTA1)
        PORTA->PCR[2] = PORT_PCR_MUX(2);         
        else if(PORT_TX == PTA2)
          PORTA->PCR[2] = PORT_PCR_MUX(2); 
        else if(PORT_TX == PTA14)
          PORTA->PCR[14] = PORT_PCR_MUX(3); 
        else
          PORTB->PCR[17] = PORT_PCR_MUX(3); 

        if(PORT_RX == PTA1)
          PORTA->PCR[1] = PORT_PCR_MUX(2); 
        else if(PORT_RX == PTA15)
          PORTA->PCR[15] = PORT_PCR_MUX(3); 
        else
          PORTB->PCR[16] = PORT_PCR_MUX(3); 
        
        
       UART_C2_REG((g_UART_MemMapPtr)uartn)&=~(0|UART_C2_TE_MASK|UART_C2_RE_MASK);
       UART_C1_REG((g_UART_MemMapPtr)uartn)|=(0|UART_C1_PE_MASK|UART_C1_PT_MASK);
       
       
       if((uartn==g_UART0)||(uartn==g_UART1))
       {
       sysclk=g_core_clock*1000;
       }
       else
       {
       sysclk=g_core_clock*1000;
       }
       sbr=(uint16)(sysclk/(baud*16));
       if(sbr>0x1FFF)
         sbr=0x1FFF;
       brfa=(sysclk/baud)-(sbr*16);
       temp=UART_BDH_REG((g_UART_MemMapPtr)uartn)&(~UART_BDH_SBR_MASK);
       UART_BDH_REG((g_UART_MemMapPtr)uartn)=temp|UART_BDH_SBR(sbr>>8);
       UART_BDL_REG((g_UART_MemMapPtr)uartn)=UART_BDL_SBR(sbr);
       temp=UART_C4_REG((g_UART_MemMapPtr)uartn)&(~UART_C4_BRFA_MASK);
       UART_C4_REG((g_UART_MemMapPtr)uartn)=temp|UART_C4_BRFA(brfa);
       UART_PFIFO_REG((g_UART_MemMapPtr)uartn)|=(0|UART_PFIFO_TXFE_MASK|UART_PFIFO_RXFE_MASK);
       UART_C2_REG((g_UART_MemMapPtr)uartn)|=(0|UART_C2_TE_MASK|UART_C2_RE_MASK);
     }
}



void uart_send1(UARTn uartn,uint8 ch)
{
while(!(((g_UART_MemMapPtr)uartn)->S1&UART_S1_TDRE_MASK));
UART_D_REG((g_UART_MemMapPtr)uartn)=ch;
}


void uart_sendn(UARTn uartn,uint16 len,uint8 *buff)
{
for(int n=0;n<len;n++)
{
uart_send1(uartn,*(buff++));
}
}


void uart_re1(UARTn uartn,uint8 fp)
{
while(!(((g_UART_MemMapPtr)uartn)->S1)&UART_S1_RDRF_MASK);
fp=(((g_UART_MemMapPtr)uartn)->D);

       
void uart_enable_re_init(UARTn uartn)
{
(((g_UART_MemMapPtr)uartn)->C2)|=UART_C2_TIE_MASK;
if(uartn == g_UART2)
enable_irq((int) (( ( (UART0_BASE/*(uint32)uartn*/)>>12 )&0x0000000Fu ) - 0x0000000A + (uint32)UART0_RX_TX_IRQn));
}
         
         
void uart_disable_re_init(UARTn uartn)
{
UART_C2_REG((g_UART_MemMapPtr)uartn)&=~UART_C2_TIE_MASK;
if(!(UART_C2_REG((g_UART_MemMapPtr)uartn))&(UART_C2_TIE_MASK|UART_C2_TCIE_MASK))
disable_irq((int) (( ( (UART0_BASE/*(uint32)uartn*/)>>12 )&0x0000000Fu ) - 0x0000000A + (uint32)UART0_RX_TX_IRQn));
}
main.c

#include "common.h"
#include "gpio.h"
   
enum LEDn
{
LEDG=10,
LEDR=11,
LEDB=12,
};
enum led_status
{
  led_on=1,
  led_down=0,
};


void main (void)
{
 //printf("hello world");
  g_LPLD_GPIO_Init(PTA ,LEDG ,DIR_OUTPUT ,1);
    g_LPLD_GPIO_Init(PTA ,LEDR ,DIR_OUTPUT ,1);
    g_LPLD_GPIO_Init(PTA ,LEDB ,DIR_OUTPUT ,1);
  while(1)
  {
    
    delay_ms(50);
    g_LPLD_GPIO_Set(PTA ,LEDB ,0);
    delay_ms(50);
    g_LPLD_GPIO_Set(PTA ,LEDB ,1);
    delay_ms(50);
    g_LPLD_GPIO_Set(PTA ,LEDG ,0);
    delay_ms(50);
    g_LPLD_GPIO_Set(PTA ,LEDG ,1);
    delay_ms(50);
    g_LPLD_GPIO_Set(PTA ,LEDR ,0);
    delay_ms(50);
    g_LPLD_GPIO_Set(PTA ,LEDR ,1); 
  } 
}

总结:上面的很多都是自己敲的,最后都最后实现流水灯真的很不易,很多bug都是学长帮助改的,但当真正的实现一些功能,还是觉得很值的。希望接下来自己能更加的努力,争取能够完成十二月份的校内赛。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值