5. POS秤分享与总结
本次通过TOPWAY7寸智能屏,设计了一个POS秤,本次试用活动过程还是写了不少的代码,在本帖子里面将其开源,共享。液晶屏仅为数据显示,而数据的控制与采集全部来自AT32单片机,下面是编写的一些驱动。
//****************************************************************
//******  SPI GPIO 初始化函数
//******  输入参数: 无
//******  返回值:   无
//****************************************************************
void PhySpiGpioInit()
{
   gpio_init_type gpio_initstructure;
   crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
   // CS  PA4
   gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;  
   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;  
   gpio_initstructure.gpio_mode           = GPIO_MODE_OUTPUT;  
   gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
   gpio_initstructure.gpio_pins = GPIO_PINS_4;
   gpio_init(GPIOA, &gpio_initstructure);
   gpio_bits_set(GPIOA, GPIO_PINS_4);   // FLASH_CS_HIGH
   // SCK PA5
   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;  
   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;  
   gpio_initstructure.gpio_pins = GPIO_PINS_5;
   gpio_init(GPIOA, &gpio_initstructure);
   // MISO  PA6
   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;  
   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;  
   gpio_initstructure.gpio_pins = GPIO_PINS_6;
   gpio_init(GPIOA, &gpio_initstructure); 
   // MOSI PA7
   gpio_initstructure.gpio_pull           = GPIO_PULL_UP;  
   gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;  
   gpio_initstructure.gpio_pins = GPIO_PINS_7;
   gpio_init(GPIOA, &gpio_initstructure);   
}
//****************************************************************
//******  SPI 参数配置初始化函数
//******  输入参数: 无
//******  返回值:   无
//****************************************************************
void PhySpiCoreInit()
{
   spi_init_type spi_init_struct;
   crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);
   crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE);
   spi_default_para_init(&spi_init_struct);
    
   spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
   spi_init_struct.master_slave_mode = SPI_MODE_MASTER;  //主机
   spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_8;  //
   spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
   spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
   spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
   spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE;
   spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
   spi_init(SPI1, &spi_init_struct);
   spi_enable(SPI1, TRUE);
    
}
//****************************************************************
//******  SPI 初始化函数
//******  输入参数: 无
//******  返回值:   无
//****************************************************************
void PhySpiInit()
{
   PhySpiGpioInit();
   PhySpiCoreInit(); 
}
//****************************************************************
//******  SPI 发送和接收一个字节数据 函数
//******  输入参数: uint32_t erase_addr     块擦除所在的地址
//******  返回值:   uint8_t 接收的数据
//****************************************************************
uint8_t PhySpiByteWrite(uint8_t data)
{
  uint8_t brxbuff;
  spi_i2s_dma_transmitter_enable(SPI1, FALSE);
  spi_i2s_dma_receiver_enable(SPI1, FALSE);
  spi_i2s_data_transmit(SPI1, data);
  while(spi_i2s_flag_get(SPI1, SPI_I2S_RDBF_FLAG) == RESET);
  brxbuff = spi_i2s_data_receive(SPI1);
  while(spi_i2s_flag_get(SPI1, SPI_I2S_BF_FLAG) != RESET);
  return brxbuff;
}
//****************************************************************
//******  串口GPIO初始化函数
//******  输入参数: 无
//******  返回值:   无
//****************************************************************
static void PhyUartGpioInit()
{
  gpio_init_type gpio_init_struct;
  crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
  gpio_default_para_init(&gpio_init_struct);
    
  gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
  gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
  gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
  gpio_init_struct.gpio_pins = GPIO_PINS_9|GPIO_PINS_10;
  gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
  gpio_init(GPIOA, &gpio_init_struct);
    
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE9, GPIO_MUX_1); 
  gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE10, GPIO_MUX_1); 
    
}
//****************************************************************
//******  串口参数初始化函数
//******  输入参数: uint32_t baudrate 波特率
//******  返回值:   无
//****************************************************************
static void  PhyUartCoreInit(uint32_t baudrate)
{
   crm_periph_clock_enable(CRM_USART1_PERIPH_CLOCK, TRUE);
   usart_init(USART1, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT);
   usart_parity_selection_config(USART1, USART_PARITY_NONE);
   usart_transmitter_enable(USART1, TRUE); 
   usart_receiver_enable(USART1, TRUE); 
   usart_dma_receiver_enable(USART1, TRUE); 
   nvic_irq_enable(USART1_IRQn, 0, 0);
   usart_interrupt_enable(USART1, USART_IDLE_INT, TRUE);    
   usart_enable(USART1, TRUE);        
}
//****************************************************************
//******  串口DMA参数初始化函数
//******  输入参数: 无
//******  返回值:   无
//****************************************************************
void PhyUartDmaInit()
{
  dma_init_type dma_init_struct;  
  crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);  
  
  dma_reset(DMA1_CHANNEL3);
  dma_default_para_init(&dma_init_struct);  
  dma_init_struct.buffer_size = USART_RX_BUFFER_SIZE;
  dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
  dma_init_struct.memory_base_addr = (uint32_t)UartRxBuffer;
  dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE;
  dma_init_struct.memory_inc_enable = TRUE;
  dma_init_struct.peripheral_base_addr = (uint32_t)&USART1->dt;
  dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_BYTE;
  dma_init_struct.peripheral_inc_enable = FALSE;
  dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
  dma_init_struct.loop_mode_enable = FALSE; 
  dma_init(DMA1_CHANNEL3, &dma_init_struct);
  dma_channel_enable(DMA1_CHANNEL3, TRUE); 
}
//****************************************************************
//******  串口初始化函数
//******  输入参数: 无
//******  返回值:   无
//****************************************************************
void PhyUartInit()
{
    PhyUartGpioInit();
    PhyUartDmaInit();
    PhyUartCoreInit(115200);
}
//****************************************************************
//******  串口发送双字节函数
//******  输入参数: uint16_t DataByte :发送双字节
//******  返回值:   无
//****************************************************************
void PhyUartSendByte(uint8_t Byte)
{
    USART1->dt_bit.dt = Byte;
    while(USART1->sts_bit.tdc == RESET);   
}
//****************************************************************
//******  串口中断处理函数
//******  输入参数: 无
//******  返回值:   无
//****************************************************************
void USART1_IRQHandler()
{
  uint16_t rc_len;
  if(usart_flag_get(USART1, USART_IDLEF_FLAG) != RESET)
  {
      usart_data_receive(USART1);
      dma_channel_enable(DMA1_CHANNEL3,FALSE); 
      rc_len = USART_RX_BUFFER_SIZE - dma_data_number_get(DMA1_CHANNEL3);
      dma_data_number_set(DMA1_CHANNEL3, USART_RX_BUFFER_SIZE);
      dma_channel_enable(DMA1_CHANNEL3,TRUE); 
      if((UartRxBuffer[1]==0x99) && (rc_len == 8))  //处理升级帧
      {
         JumpToBoot();	          
      }     
  }
}
部分QT 代码
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ForeachPort();
    current_date_time =QDateTime::currentDateTime();
    current_date =current_date_time.toString("yyyy.MM.dd hh:mm:ss ddd");
    connect(timer0, SIGNAL(timeout()), this, SLOT(Time0out()));
    timer0->start(1000);
    this->setWindowTitle("智能Pos秤  " + current_date);
}
MainWindow::~MainWindow()
{
    delete ui;
}
//自动获取有效的串口号
void MainWindow::ForeachPort()
{
    //使用foreach获取有效的串口信息
    ui->comboBox_Port->clear();
    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        //这里相当于自动识别串口号之后添加到了cmb,如果要手动选择可以用下面列表的方式添加进去
        Serial.setPort(info);
        ui->comboBox_Port->addItem(info.portName());
    }
}
//刷新走时
void MainWindow::Time0out()
{
    current_date_time =QDateTime::currentDateTime();
    current_date =current_date_time.toString("yyyy.MM.dd hh:mm:ss ddd");
    this->setWindowTitle("智能Pos秤  " + current_date);
}
void MainWindow::on_pushButton_clicked()
{
        if(ui->pushButton->text() == "连接设备")
        {
            Serial.setPortName(ui->comboBox_Port->currentText());
            if(Serial.open(QIODevice::ReadWrite) == false)
            {
               QMessageBox::warning(this,"警告","打开失败,请检查对应的端口号!");
               return;
            }
            ui->pushButton->setText("断开设备");
         }
        else if(ui->pushButton->text() == "断开设备")
        {
           ui->pushButton->setText("连接设备");
           Serial.clear();
           Serial.close();
        }
}
void MainWindow::on_toolButton_clicked()
{
    quint8 sendData[11];
    sendData[0] = 0xAA;            //设备ID
    sendData[1] = 0x42;      //命令码
    sendData[2] = 0x00;            //数据
    sendData[3] = 0x00;
    sendData[4] = 0x00;
    sendData[5] = 0x80;
    sendData[6] = 0x31;
    sendData[7] = 0x00;
    sendData[8] = 0xCC;
    sendData[9] = 0x33;
    sendData[10] = 0xC3;
    sendData[11] = 0x3C;
    Serial.write((char *)sendData,11);
}