lpc1768

概述


1、I2C,

     I2C每次只能读写一个字节,读写过程就是操作相关寄存器,读取或者填充数据到外部缓冲区中;

     EEPROM使用的I2C来完成读写;


2、GPIO

     包含多个端口,每个端口包含引脚;

     每个引脚,可以配置:输入还是输出,方向,开漏模式;

     使用GPIO的模块有:AD采集,BEEP控制,LED控制,VALVE控制,PUMP控制,PWM控制,FAN控制;

     

     附:8种工作模式定义;

     (1)GPIO_Mode_AIN 模拟输入 
     (2)GPIO_Mode_IN_FLOATING 浮空输入 
     (3)GPIO_Mode_IPD 下拉输入 
     (4)GPIO_Mode_IPU 上拉输入 
     (5)GPIO_Mode_Out_OD 开漏输出 
     (6)GPIO_Mode_Out_PP 推挽输出 
     (7)GPIO_Mode_AF_OD 复用开漏输出 
     (8)GPIO_Mode_AF_PP 复用推挽输出


Timer


#include "deftype.h"
#include "lpc17xx.h"
#include "timer.h"
#include "stdlib.h"


/***********************************************************************/
//函数声明
timer_ch* seek_timer_ch(uint32 ucTimerCh);
/***********************************************************************/
//宏定义


//定时器时钟定义
#define TIMER_PERI_CLOCK        (18000000) /*!< 72MHz/4=18MHz */


//变量定义
timer_ch  timer_num = {0};//定时器链表头
timer_ch_tail timer_num_tail = {0};//定时器链表尾


int32 timer_init(void)
{   
  LPC_SC->PCONP |= (1 << 1);
  LPC_TIM0->MR0 = (TIMER_PERI_CLOCK/1000 * TIMER0_INT_VALUE) - 1;
  LPC_TIM0->MCR = 0x03; /*使能中断,并且中断后复位计数器*/
  NVIC_EnableIRQ(TIMER0_IRQn);
  LPC_TIM0->TCR = 0x01;
  
  timer_num.next = NULL;
  timer_num.timer_ch = DELAY_10MS;
  timer_num.timer_count = 0;
  timer_num.timer_data = TIMER0_DELAY_10MS;
  timer_num.phandle = NULL;
  timer_num_tail.timer_tail = &timer_num;
  timer_num_tail.cnt = 0;
  return EXIT_SUCCESS;
}


void disable_timer(void)
{
  LPC_TIM0->TCR = 0x00;
}


int32 check_timer_delay( uint8 ucTimerCh)
{   
    timer_ch* timer_ch_return = NULL;
    
    //查询定时器变量
    timer_ch_return = seek_timer_ch(ucTimerCh);
    //没有找到
    if(NULL == timer_ch_return)
    {
      return NONE_SCHEDULE;
    }
    //找到处理
    else
    { 
      //定时到
      if(timer_ch_return->timer_count >= timer_ch_return->timer_data)
      { 
        //清零计数
        timer_ch_return->timer_count = 0;
        //调用处理函数
        if(NULL != timer_ch_return->phandle)
        {
          timer_ch_return->phandle();
        }
        return MEET_SCHEDULE;
      }
      //定时未到
      else
      {
        return NONE_SCHEDULE;
      }
    }
   
}


uint32 get_timer_ch_num(void)
{
  return timer_num_tail.cnt;
}


void timer_ch_insert(timer_ch_tail *tail,timer_ch* var,uint32 ucTimerCh,uint32 ucTimerDat,pfunction pfunchandle)

  if(tail->timer_tail != NULL)
  {
    //链表尾插入定时变量
    tail->timer_tail->next = var;
    tail->timer_tail->next->timer_ch = ucTimerCh;
    tail->timer_tail->next->timer_data = ucTimerDat;
    tail->timer_tail->next->timer_count = 0;
    tail->timer_tail->next->phandle = pfunchandle;
    tail->timer_tail->next->next = NULL;
    tail->cnt++;
  }
  
}


int32 insert_timer_ch(uint32 ucTimerCh,uint32 ucTimerDat,pfunction pfunchandle)
{
  timer_ch* ptimer_ch = NULL;
  
  ptimer_ch = malloc(sizeof(timer_ch));
  //内存分配判断
  if(ptimer_ch == NULL)
  {
    return EXIT_FAILURE;
  }
  
  //链表尾插入定时变量
  timer_ch_insert(&timer_num_tail,ptimer_ch,ucTimerCh,ucTimerDat,pfunchandle);
  //更新链表尾指针
  timer_num_tail.timer_tail = ptimer_ch;
  
  return EXIT_SUCCESS;  
}


timer_ch* seek_timer_ch(uint32 ucTimerCh)
{
  timer_ch* timer_ch_return = NULL;
  
  timer_ch_return = &timer_num;  
  for(;timer_ch_return != NULL;timer_ch_return = timer_ch_return->next)
  {
    if(ucTimerCh == timer_ch_return->timer_ch)
    {
      return timer_ch_return;
    }
  }
  return (timer_ch*)0;
}


void set_timer_counter(uint32 ucTimerCh, uint32 unCnt)
{
  timer_ch* timer_ch_return = NULL;
  
  timer_ch_return = seek_timer_ch(ucTimerCh);
  timer_ch_return->timer_count = unCnt;
}


uint32 get_timer_counter(uint32 ucTimerCh)
{
   timer_ch* timer_ch_return = NULL;
   
   timer_ch_return = seek_timer_ch(ucTimerCh);
   return timer_ch_return->timer_count;
}


void set_timer_delay(uint32 ucTimerCh, uint32 unDelay)
{
  timer_ch* timer_ch_return = NULL;
  
  timer_ch_return = seek_timer_ch(ucTimerCh);
  timer_ch_return->timer_data = unDelay;
}


void TIMER0_IRQHandler(void)
{
    timer_ch* timer_ch_return = NULL;


    //清除定时器中断标志
    LPC_TIM0->IR = 0x01;
    //更新定时值
    timer_ch_return = &timer_num;
    for(;timer_ch_return != NULL;timer_ch_return = timer_ch_return->next)
    {
      timer_ch_return->timer_count++;
    }
}


Main

/************************************************************/
//app实现
int main(void)

  uint8 i = 0;


  //上电初始化
  //初始化定时器
  timer_init();
  
  led_init(leds,LED_NUM);
  //插入led_state定时器变量
  insert_timer_ch(LED_STATE_DELAY_LOCOAL,TIMER0_DELAY_200MS,led_state_toggle);
  
  pcb_version_init(versions,VER_NUM);
  com_type_init(com_type,COM_TYPE_NUM);
  com_port_init(DEBUGPORT,COMMPORT);
  
  //串口初始化
  uart_init(UART0_PORT_NUM,115200,160,DATA_BITS_8,STOP_BITS_1,PARITY_NONE);
  uart_init(UART1_PORT_NUM,115200,512,DATA_BITS_8,STOP_BITS_1,PARITY_NONE);
  
  //初始化adc
  adc_init(AD_CH(0));//正压
  adc_init(AD_CH(1));//负压
  adc_init(AD_CH(2));//鞘流压
  
  //fpga初始化
  fpga_init();
  //插入定时器变量
  insert_timer_ch(FPGA_CONF_DONE_DELAY_LOCOAL,TIMER0_DELAY_200MS,NULL);
  //等待fpga初始化完成
  wait_fpga_conf_done();
  //初始化can,设置报文滤波的发送节点和接受节点
can_init(CAN1,500000,CAN_MAIN_ID,CAN_LOCAL_ID);
  //插入can连接状态延时变量
  insert_timer_ch(PRINT_CAN_STATE_DELAY_LOCOAL,TIMER0_DELAY_50MS,can_con_state_process);
  //温控通道初始化
  pwm_port_init(pwms,PWM_PERIOD_CNT,pwn_drive_active,pwm_channel,PWM_NUM);
  //上电信息输出
  put_string("\r\n\r\nDriverBoard power on. PCB Version:");
  put_dec(get_pcb_version(), NULL);
  if(get_comm_port_type() == COMM_TYPE_CAN)
  {
    put_string(", CAN communication.\r\n");
  }
  else
  {
    put_string(", UART communication.\r\n");
  }
  put_string("Build Date:");
  put_string(__DATE__);
  put_string(", Time:");
  put_string(__TIME__);
  put_string(".\r\n");
  
  //关闭所有泵
  if(0 > set_pump_state(ALL_PUMP, TURN_OFF_PUMP,PUMP_DRIVE))
  {
    exit_main_func("E:turn off all pump error!", __FILE__, __LINE__);
  }
  //关闭所有阀
  if(0 > set_valve_state(ALL_VALVE, TURN_OFF_VALVE))
  {
    exit_main_func("E:turn off all valve error!", __FILE__, __LINE__);
  }
  //初始化时序包相关数据结构
  init_timeseq_struct();
  //插入定时器变量
  //用于打印时序执行时间
  insert_timer_ch(PRINT_TIMESEQ_EXEC_TIME_DELAY_LOCOAL,TIMER0_DELAY_1MS,NULL);
  //用于时序包调度
  insert_timer_ch(TIMESEQ_DELAY_LOCOAL,TIMER0_DELAY_10MS,timeseq_control);
  
  //初始化电机结构体
  if(0 > init_motor_struct())
  {
    exit_main_func("E:Init motor struct error!", __FILE__, __LINE__);
  }
  else
  {
     //插入电机动作延时定时器变量
    insert_timer_ch(MOTOR_DELAY_LOCOAL,TIMER0_DELAY_10MS,check_motor_action_delay);
  }
  
  //初始化采样组件结构体
  if(0 > init_sample_struct())
  {
    exit_main_func("E:Init sample struct error!", __FILE__, __LINE__);
  }
  else
  {
    insert_timer_ch(SAMPLE_DELAY_LOCOAL,TIMER0_DELAY_10MS,check_sample_action_delay);
  }
  
  //初始化压力运行相关数据结构
  if(0 > init_pressure_struct(pdefault_pressure_cfg))
  {
    exit_main_func("E:Init pressure struct error!", __FILE__, __LINE__);
  }
  else
  {
    //插入压力监控定时器变量
    insert_timer_ch(MONITOR_PRESSURE_DELAY_LOCOAL,TIMER0_DELAY_10MS,monitor_pressure_process);
    //插入建压延时
    insert_timer_ch(BUILD_PRESSURE_DELAY_LOCOAL,TIMER0_DELAY_10MS,pressure_process);
  }
  
  //初始化试剂相关数据结构
  if(0 > init_reagent_struct(REAGENT_CH_NUM,preagent_default_ch_cfg))
  {
    exit_main_func("E:Init reagent struct error!", __FILE__, __LINE__);
  }
  else
  {
    //插入试剂检测延时
    insert_timer_ch(REAGENT_DELAY_LOCOAL,TIMER0_DELAY_1MS,reagent_process);
    //插入开关检测延时
    insert_timer_ch(SWITCH_DELAY_LOCOAL,TIMER0_DELAY_1000MS,switch_process);
  }
  
  //初始化温度控制相关数据结构
  if(0 > init_temp_struct(TEMP_CH_NUM,pwn_drive_active,pdefault_temp_ctl_cfg))
  {
    exit_main_func("E:Init temp struct error!", __FILE__, __LINE__);
  }
  else
  {
    //插入温度控制延时变量
    //insert_timer_ch(TEMP_DELAY_LOCOAL,TIMER0_DELAY_1000MS,temperature_process);
    insert_timer_ch(TEMP_DELAY_LOCOAL,TIMER0_DELAY_1000MS,temperature_process);
  }
  
  //led亮,进入主循环
  led_state_on();
  led_flash_off();
  put_string("Power on ok, enter main loop.\r\n");
  //插入MCU复位延时变量
  insert_timer_ch(MCU_RESET_DELAY_LOCOAL,TIMER0_DELAY_500MS,NULL);
    
  while(1)
  {
    for(i = 1;i <= 14;i++)
    {
      check_timer_delay(i);
    }
    //电机控制
    if(0 > motor_process())
    {
        put_string("E:Motor process error!\r\n");
    }
    //采样组件控制
    if(0 > sample_process())
    {
      put_string("E:Sample process error!\r\n");
    }
    //通信协议
    if(0 > protocol_process())
    {
      put_string("E:Protocol process error!\r\n");
    }
  }
  
}



AD

void start_ad_convert(uint8 ad_ch)
{
  volatile uint32 unused = 0;
  
  unused = LPC_ADC->ADGDR; //清除全局数据寄存器转换完成标志
  LPC_ADC->ADCR &= 0xf8ffffff;//停止转换
  LPC_ADC->ADCR &= 0xffffff00;//通道号复位
  LPC_ADC->ADCR |= AD_CH_SEL(ad_ch);//选择AD通道
  LPC_ADC->ADCR |= AD_START(1);//立即启动转换 
}


uint16 get_ad_value(uint8 ad_ch)
{
  uint16 ad_value = 0x0000;
  uint32 ad_adgdr = 0;
  uint32 i = 0;
  
  if(ad_ch > 7)
  {
    return AD_CONVERT_ERR;
  }
  //启动转换
  start_ad_convert(ad_ch);
  //等待转换完成
  while(1)
  {
    ad_adgdr = LPC_ADC->ADGDR;//查询全局数据寄存器
    if(AD_CONVERT_DONE == (ad_adgdr & AD_CONVERT_DONE))//判断AD转换是否完成
    {
      if(((uint8)(ad_adgdr>>24) & 0x07) == ad_ch)//判断是否是指定通道的AD
      {
        ad_value = (uint16)(ad_adgdr>>4) & 0x0fff;
      }
      else
      {
        ad_value = AD_CONVERT_ERR;
      }
      
       LPC_ADC->ADCR &= 0xf8ffffff;//停止转换
       i = 0;
       break;
    }
    
    i++;
    if(720000 < i)//10ms
    {
      ad_value = AD_CONVERT_ERR;
      i = 0;
      break;
    }
  }
  return ad_value;
}


void adc_init(uint8 ad_ch)
{
  io_st io_to_ad[8] = {\
        {GPIO_PORT(0),GPIO_PIN(23),PIN_FUNC(1),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW},//AD0.0
        {GPIO_PORT(0),GPIO_PIN(24),PIN_FUNC(1),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW},//AD0.1
        {GPIO_PORT(0),GPIO_PIN(25),PIN_FUNC(1),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW},//AD0.2
        {GPIO_PORT(0),GPIO_PIN(26),PIN_FUNC(1),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW},//AD0.3
        {GPIO_PORT(1),GPIO_PIN(30),PIN_FUNC(3),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW},//AD0.4
        {GPIO_PORT(1),GPIO_PIN(31),PIN_FUNC(3),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW},//AD0.5
        {GPIO_PORT(0),GPIO_PIN(3), PIN_FUNC(2),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW},//AD0.6
        {GPIO_PORT(0),GPIO_PIN(2), PIN_FUNC(2),PIN_MODE_INACTIVE,PIN_OD_DISABLE,GPIO_INPUT,GPIO_STATE_LOW} //AD0.7
        };
  //使能ADC
  LPC_SC->PCONP |= (0x01<<12);
  //ADC时钟源选择
  //默认值CCLK/4
  //配置IO为ADC功能
  set_gpio_func(io_to_ad[ad_ch].port,io_to_ad[ad_ch].pin,io_to_ad[ad_ch].func);
  set_gpio_mode(io_to_ad[ad_ch].port,io_to_ad[ad_ch].pin,io_to_ad[ad_ch].mode);
  //ADC控制寄存器设置,时钟9M
  LPC_ADC->ADCR = AD_CH_SEL(0) | AD_CLK_DIV(2) | AD_WORK_SOFT | AD_PDN_DISABLE | AD_EDGE_UP | AD_START(0);       
}


  //初始化adc
  adc_init(AD_CH(0));//正压
  adc_init(AD_CH(1));//负压
  adc_init(AD_CH(2));//鞘流压



FPGA

和FPGA交互,从FPGA读取数据,或者向FPGA写入数据;

使用场景包括:

1、通过FPGA读取温度值;

2、通过FPGA读写阀状态;

3、通过FPGA读写泵状态;

4、通过FPGA读取试剂检测占空比;

5、通过FPGA查询外部开关状态()

6、通过FPGA读取电机光耦状态,剩余运动步数;


uint8 get_checksum_from_fpga(uint16 fpga_addr)
{
  uint8 check_sum = 0;
  
  //延时
  delay_clocks();
  delay_clocks();
  //写地址
  set_fpga_addr_bus(fpga_addr);
  //延时
  delay_clocks();
  delay_clocks();
  //读信号有效
  FPGA_RD_L();
  //延时
  delay_clocks();
  delay_clocks();
  delay_clocks();
  delay_clocks();
  delay_clocks();
  delay_clocks();
  //读取
  check_sum = get_fpga_data_bus();
  //读结束
  FPGA_RD_H();
  //延时
  delay_clocks();
  
  return check_sum;
}




uint8 set_checksum_to_fpga(uint16 fpga_addr, uint8 check_sum)
{
  uint8 check_state = 0;
  
  //延时
  delay_clocks();
  delay_clocks();
  //向数据线写校验
  set_fpga_data_bus(check_sum);
  //向地址线写地址
  set_fpga_addr_bus(fpga_addr);
  //延时
  delay_clocks();
  delay_clocks();
  //写信号有效
  FPGA_WR_L();
  //延时
  delay_clocks();
  delay_clocks();
  delay_clocks();
  delay_clocks();
  delay_clocks();
  delay_clocks();
  //写结束
  FPGA_WR_H();
  //获取校验状态
  check_state = FPGA_WR_STATE();
  check_state = FPGA_WR_STATE();
  //延时
  delay_clocks();
  
  return check_state;
}




int32 fpga_read(fpga_data *pfpga_data, uint8 data_len)
{
  int32 lret = EXIT_FAILURE_LOCOAL;
  uint16 check_sum_cal = 0;
  uint8  check_sum_get = 0;
  uint8  check_sum_temp = 0;
  uint8 i = 0;
  uint8 read_times = 0;
  
  do
  {
    if(INVALID_POINTER(pfpga_data) || (1 > data_len))
    {
//      debug_msg("E:input param error!",__FILE__,__LINE__);
      break;
    }
    //置数据线为输入
    FPGA_WR_H();
    FPGA_RD_H();
    set_fpga_data_bus_dir(GPIO_INPUT);
    
    while(1)
    { 
      //片选有效
      FPGA_CS_L();
      check_sum_cal = 0;
      //延时
      delay_clocks();
      
      for(i = 0;i < data_len;i++)
      {
        //写地址
        set_fpga_addr_bus(pfpga_data[i].addr);
        //计算校验和,包括地址和数据
        check_sum_cal += pfpga_data[i].addr;
        //延时
        delay_clocks();
        //单次读有效
        FPGA_RD_L();
        //延时
        delay_clocks();
        delay_clocks();
        delay_clocks();
        delay_clocks();
        delay_clocks();
        delay_clocks();
        //读取数据
        pfpga_data[i].data = get_fpga_data_bus();
        //计算校验和
        check_sum_cal += pfpga_data[i].data;
        //单次读结束
        FPGA_RD_H();
        //延时
        delay_clocks();
      }
      //延时
      delay_clocks();
      delay_clocks();
      //片选无效
      FPGA_CS_H();
      
      //读校验
      check_sum_get = get_checksum_from_fpga(REG_ARM_READ_CHECKSUM);
      //校验比较
      check_sum_temp = (uint8)(check_sum_cal & 0x00ff);
      check_sum_temp += (uint8)(check_sum_cal >> 8);
      check_sum_temp = ~check_sum_temp;
      if(check_sum_get != check_sum_temp)
      {
        //读失败重复读,次数限制3次
        if(read_times < 3)
        {
          read_times++;
        }
        else
        {
          break;
        }
      }
      else //校验正确
      {
        lret = EXIT_SUCCESS_LOCOAL;
        break;
      }
    }
  }while(0);
  
  return lret;
}


int32 fpga_write(fpga_data *pfpga_data, uint8 data_len)
{
  int32 lret = EXIT_FAILURE_LOCOAL;
  uint16 check_sum_cal = 0;
  uint8  check_sum_temp = 0;
  uint8 i = 0;
  uint8 write_times = 0;
  
  do
  {
    if(INVALID_POINTER(pfpga_data) || (1 > data_len))
    {
//      debug_msg("E:input param error!",__FILE__,__LINE__);
      break;
    }
    
    //置数据线为输出
    FPGA_RD_H();
    FPGA_WR_H();
    set_fpga_data_bus_dir(GPIO_OUTPUT);
    
    while(1)
    {
      //片选有效
      FPGA_CS_L();
      check_sum_cal = 0;
      
      for(i = 0;i < data_len;i++)
      {  
        //延时
        delay_clocks();
        //向数据总线上写数据
        set_fpga_data_bus(pfpga_data[i].data);
        check_sum_cal += pfpga_data[i].data;
        //向地址线写地址
        set_fpga_addr_bus(pfpga_data[i].addr);
        check_sum_cal += pfpga_data[i].addr;
        //延时
        delay_clocks();
        //单次写信号有效
        FPGA_WR_L();
        //延时
        delay_clocks();
        delay_clocks();
        delay_clocks();
        delay_clocks();
        delay_clocks();
        delay_clocks();
        //单次写结束
        FPGA_WR_H();
        //延时
        delay_clocks();        
      }
      //延时
      delay_clocks();
      //片选失效
      FPGA_CS_H();
      //写校验
      check_sum_temp = (uint8)(check_sum_cal & 0x00ff);
      check_sum_temp += (uint8)(check_sum_cal >> 8);
      check_sum_temp = ~check_sum_temp;
      if(WR_FPGA_CKECKSUM_ERR == set_checksum_to_fpga(REG_ARM_WRITE_CHECKSUM, check_sum_temp))
      {
//        debug_msg("E:fpga ReWR!",__FILE__,__LINE__);
        if(write_times < 3)
        {
          write_times++;
        }
        else
        {
//          debug_msg("E:fpga write error!",__FILE__,__LINE__);
//          lret = -ERR_DB_WRITE_FPGA;
          break;
        }
      }
      else
      {
        lret = EXIT_SUCCESS_LOCOAL;
        break;
      }
    }
   //数据总线置为输入
   set_fpga_data_bus_dir(GPIO_INPUT);
  }while(0);
  
  return lret;
}



  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值