Global Application_Start 定时器 不进断点

作者在使用.NET Framework 4.0的Web项目中遇到Application_Start方法不触发的问题,仅在特定配置下生效。本文探讨了该问题可能的原因及解决方案。
我的 web 项目是 .net framework 4.0 版本的。用到了 Global 类中的 Application_Start 方法,但是经过数次试验发现,只有当我采用 Visual Studio 2010 调试,或者将 win7 上的 IIS7.5 对应我的项目的应用程序池改为“经典”才行,而一旦用“集成”模式,则无论怎么替换 bin 下的 dll,或者修改 web.config 或者重启 IIS 甚至重启系统,在调试时都不进入我在 Application_Start 方法中设置的断点。而同一个类中的 Application_BeginRequest 方法倒是无论什么情况都可以正常被调用。,这是怎么回事呢???谢谢大家!
/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : main.c * @brief : Main program body ****************************************************************************** * @attention * * Copyright (c) 2025 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "adc.h" #include "dma.h" #include "i2c.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ #include "math.h" #include "font6x8.h" #include "sdd1306.h" #include "key.h" #include "stdio.h" #include "vofa.h" /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ #define K1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_11) #define K2 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_12) #define K7 HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_15) int a,b,c,d; float f=0.5;float f1=1;float f2=2;float z=0; float t=3.14/4; int n =1; //初始值 uint16_t current_freq = 1000; uint16_t current_duty = 50; uint32_t high_time; //高电平时间 // 捕获到的输入信号参数(来自 TIM2_CH2 对 PA1 的捕获) uint16_t captured_freq = 0; // 初始值 float captured_duty = 0.0f; // 初始值 // 输入捕获状态机缓冲区 uint32_t cap_buf[3] = {0}; uint8_t cap_cnt = 0; /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ uint8_t rx_data; // 接收单字节 char rx_buffer[32]; // 存储完整命令 int rx_index = 0; // 缓冲区索引 /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ static void BreathingLight(void){ float t1 = HAL_GetTick()*0.001; float duty1 = 0.5 * sin(f*3.14*t1+a*t/f)+0.5; uint16_t arr1 = __HAL_TIM_GET_AUTORELOAD(&htim1); uint16_t ccr1 = duty1 * (arr1+1); __HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,ccr1); float t2 = HAL_GetTick()*0.001; float duty2 = 0.5 * sin(f*3.14*t2+b*t/f)+0.5; uint16_t arr2 = __HAL_TIM_GET_AUTORELOAD(&htim2); uint16_t ccr2 = duty2* (arr2+1); __HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,ccr2); float t3 = HAL_GetTick()*0.001; float duty3 = 0.5 * sin(f*3.14*t3+c*t/f)+0.5; uint16_t arr3 = __HAL_TIM_GET_AUTORELOAD(&htim3); uint16_t ccr3 = duty3 * (arr3+1); __HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_1,ccr3); float t4 = HAL_GetTick()*0.001; float duty4 = 0.5 * sin(f*3.14*t4+d*t/f)+0.5; uint16_t arr4 = __HAL_TIM_GET_AUTORELOAD(&htim4); uint16_t ccr4 = duty4 * (arr4+1); __HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_3,ccr4); } //static void UpdateOLEDDisplay(void) //{ // uint32_t psc = htim1.Init.Prescaler; // uint32_t arr = htim1.Init.Period; // // float timer_clock_freq = (float)HAL_RCC_GetPCLK2Freq(); // float freq = timer_clock_freq / ((arr + 1) * (psc + 1)); // // // 3. 获取TIM1通道1的比较值(CCR) // uint32_t ccr = __HAL_TIM_GET_COMPARE(&htim1, TIM_CHANNEL_2); // // // 4. 计算占空比 // float duty_cycle = (float)ccr / (arr + 1) * 100.0f; // 转换为百分比 // char display_buf[32]; // // // 3. 将数值格式化为字符串 // sprintf(display_buf, "Freq: %.1f Hz", freq); // OLED_ShowString(0, 0, (uint8_t*)display_buf, 16); // // // sprintf(display_buf, "Duty: %.1f %%", duty_cycle); // OLED_ShowString(0, 8, (uint8_t*)display_buf, 16); // // // OLED_DrawSquareWave(0, 48, 16, freq, duty_cycle); // OLED_UpdateDownScreen(); // OLED_UpdateScreen(); //} static void UpdateOLEDDisplay(void) { char display_buf[32]; // === 显示【输出信号】的信息 === uint32_t out_psc = htim1.Init.Prescaler; uint32_t out_arr = htim1.Init.Period; float timer_clk = (float)HAL_RCC_GetPCLK2Freq(); float output_freq = timer_clk / ((out_arr + 1) * (out_psc + 1)); uint32_t ccr = __HAL_TIM_GET_COMPARE(&htim1, TIM_CHANNEL_2); float output_duty = (float)ccr / (out_arr + 1) * 100.0f; sprintf(display_buf, "O:%.0f Hz", output_freq); OLED_ShowString(0, 0, (uint8_t*)display_buf, 16); sprintf(display_buf, "Duty:%.0f%%", output_duty); OLED_ShowString(68, 0, (uint8_t*)display_buf, 16); // 右对齐 // === 显示【输入信号】的信息 === sprintf(display_buf, "I:%d Hz", captured_freq); OLED_ShowString(0, 8, (uint8_t*)display_buf, 16); sprintf(display_buf, "Duty:%.1f%%", captured_duty); OLED_ShowString(68, 8, (uint8_t*)display_buf, 16); // === 绘制两个波形示意 === // 上半屏:输出波形 OLED_DrawSquareWaveOut(0, 32, 12, output_freq, output_duty); OLED_DrawSquareWaveIn(0, 56, 12, (float)captured_freq, captured_duty); OLED_UpdateScreen(); // 全屏刷新 } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_DMA_Init(); MX_TIM2_Init(); MX_TIM1_Init(); MX_TIM3_Init(); MX_TIM4_Init(); MX_I2C1_Init(); MX_USART3_UART_Init(); MX_ADC1_Init(); /* USER CODE BEGIN 2 */ HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); //led HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1); HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3); //信号pwm HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2); //输入捕获 HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_ICPOLARITY_RISING); // 必须设置初始极性! // 在 main 开头加 __HAL_TIM_SET_AUTORELOAD(&htim3, 999); __HAL_TIM_SET_PRESCALER(&htim3, 71); HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2); __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_2, 500); // 设置占空比为 50% // 开启串口接收中断 HAL_UART_Receive_IT(&huart3, &rx_data, 1); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ OLED_Init(); // 初始化OLED屏幕 OLED_Clear(); // 清屏,所有像素熄灭 Update_ARR(); // char str_buf[16]; while (1) { //---------------------------------------------------信号发生器加示波器----------------------------------------------------------- static uint32_t last_update = 0; if (HAL_GetTick() - last_update >= 100) { UpdateOLEDDisplay(); last_update = HAL_GetTick(); } Key_Scan_All(); // 扫描按键 //———————————————————————————流水灯-------------------------------------------------------------------- if (K1 == 0) { HAL_Delay(10); if(K1 == 0) { while(K1==0); n = -n; } } if (K2 == 0) { HAL_Delay(10); if(K2 == 0) { while(K2==0); z=f2; f2=f1; f1=f; f=z; } } if (n == 1){ a=1;b=2;c=3;d=4; BreathingLight(); } else if(n == -1){ a=4;b=3;c=2;d=1; BreathingLight(); } // //——————————————————————————————按键轮换值 // static uint8_t demo_idx = 0; // 当前演示档位索引 // // --- 12组演示数据:频率(Hz) + 占空比(%) --- //// === 符合 100Hz ~ 10kHz 的预设组合(共8组)=== //static const uint16_t demo_freqs[8] = { // 100, // 最低边界,步电机启停 // 200, // 一般PWM控制 // 500, // 中频应用 // 1000, // 标准PWM(如风扇) // 2000, // 高速PWM // 4000, // 接近音频上限 // 8000, // 高频载波 // 10000 // 上限(10kHz) //}; //static const float demo_duties[8] = { // 50.0f, // 标准方波 // 10.0f, // 小脉冲(类似传感器触发) // 90.0f, // 大导通角 // 25.0f, // 常见调光 // 75.0f, // 高功率输出 // 33.3f, // 分频常见值 // 66.7f, // 对称波形 // 5.0f // 极窄脉冲(用于测试分辨率) //}; // static uint32_t last_key_tick = 0; // // --- K7 按键切换演示数据 --- // if (HAL_GetTick() - last_key_tick >= 50) // 消抖 // { // last_key_tick = HAL_GetTick(); // if (K7 == 0) // 按下 K7 // { // demo_idx = (demo_idx + 1) % 8; // 循环切换 6 组 // out_freq = demo_freqs[demo_idx]; // 直接 // out_duty = demo_duties[demo_idx]; // 直接 // while (K7 == 0); // 等待释放,防止连发 // } // } HAL_Delay(10); // 小延时防止 CPU 占满 // Key_Scan_All(); // UpdateOLEDDisplay(); // static uint32_t last_vofa_send = 0; // if (HAL_GetTick() - last_vofa_send >= 100) // { // Send_SquareWave_VOFA(); // last_vofa_send = HAL_GetTick(); // } // switch (capture_Cnt){ // case 0: // capture_Cnt++; // __HAL_TIM_SET_CAPTUREPOLARITY(&htim2, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_2); //启动输入捕获 或者: __HAL_TIM_ENABLE(&htim5); // break; // case 3: // high_time = capture_Buf[1]- capture_Buf[0]; //高电平时间 // sprintf(str_buf, "%d", high_time); // OLED_ShowString(0, 0, str_buf, 1); // // HAL_Delay(1000); //延时1S // capture_Cnt = 0; //清空标志位 // break; // // } // //1.阻塞式发送 // HAL_UART_Transmit(&huart3,(uint8_t *)"hello world",12,0XFFFF); // HAL_Delay(500); // //2.重定向 // printf("hello world"); // HAL_Delay(500); // //3.阻塞式接收 // uint8_t Buf[5]; // HAL_UART_Receive(&huart3,Buf,5,0XFFFF); // HAL_UART_Transmit(&huart3,Buf,5,0XFFFF); // HAL_Delay(500); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC; PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /* USER CODE BEGIN 4 */ void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim == &htim2 && htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) { uint32_t current = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); switch (cap_cnt) { case 0: // 第一个上升沿 cap_buf[0] = current; __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_ICPOLARITY_FALLING); cap_cnt = 1; break; case 1: // 下降沿 cap_buf[1] = current; __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_ICPOLARITY_RISING); cap_cnt = 2; break; case 2: // 第二个上升沿 → 周期完成 cap_buf[2] = current; uint32_t period = cap_buf[2] - cap_buf[0]; uint32_t high = cap_buf[1] - cap_buf[0]; if (period > 0) { uint32_t timer_clk = HAL_RCC_GetPCLK2Freq(); uint32_t prescaler = htim2.Init.Prescaler + 1; float input_freq = (float)timer_clk / prescaler; float freq = input_freq / period; float duty = (float)high / period * 100.0f; if (freq >= 1 && freq <= 50000) // 合理范围 { captured_freq = (uint16_t)(freq + 0.5f); captured_duty = duty; } } cap_cnt = 0; __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_ICPOLARITY_RISING); break; } } } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ __disable_irq(); while (1) { } /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ 试过了,没检测上
最新发布
11-29
/** ****************************************************************************** * @file PWR_STOP/main.c * @author MCD Application Team * @version V1.0.1 * @date 11-October-2013 * @brief Main program body ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> * * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "MM32F031xxn.h" #include <math.h> //Library #include "user.h" #include "control_circuit.h" //函数声明 void on_off(uint8_t num); void uart2_report(void); void uart1_communication(void); void report2_format(void); void auto2_sending(void); void Delay_Ms(uint32_t time_ms); //变量声明 uint32_t counter_cycle, uart1_rate, uart2_rate, cntr_unse, cntr_tim14; uint16_t adc_v, voltage, o2c, o2f, o2t, o2RH, o2P; uint32_t o2p, kpa; uint8_t USART1_TXbuffer[30], USART1_RXbuffer[30], USART2_TXbuffer[30], USART2_RXbuffer[30], buf_us6300[4], report8[30]; u8 flag_pad, flag_menu, flag_light, battery, display_flag; uint16_t voltage_buffer[15], power_off_cntr; uint8_t rx_flag, code_right, code_num, flag_adj, flash_write; uint8_t USART1_RXtotal, USART1_TXtotal, USART2_RXtotal, USART2_TXtotal, flag_preparing_report, sensor_num; float o2c_factor, o2f_factor, atm, temperature; uint8_t I2C1_Tx_Buffer[16]; uint8_t I2C1_Rx_Buffer[16]; //void data_init(void) //{ // STMFLASH_Read (FLASH_STORE_BASE_ADDR,(uint8_t*)I2C1_Rx_Buffer,16); // if((I2C1_Rx_Buffer[0]==0xAA)&&(I2C1_Rx_Buffer[3]==0x55)) // { // o2c_add = I2C1_Rx_Buffer[1]; // o2f_add = I2C1_Rx_Buffer[2]; // } // else // { // I2C1_Tx_Buffer[0] = 0xAA; // I2C1_Tx_Buffer[1] = o2c_add; // I2C1_Tx_Buffer[2] = o2f_add; // I2C1_Tx_Buffer[3] = 0x55; // STMFLASH_Write(FLASH_STORE_BASE_ADDR,(uint8_t*)I2C1_Tx_Buffer,16); // } // if(o2f_add>0x80) // o2f_factor = 1 + 0.01*(o2f_add - 0x80); // else // o2f_factor = 1 - 0.01*(0x80-o2f_add); //} int main(void) { GPIO_InitTypeDef GPIO_InitStructure; uint32_t i; uint8_t enable; for (i=0;i<MILLISECOND*64*10;i++){} // 这段延时可省去: // ------初始化全局变量------------ o2c = 210; o2f = 0; sensor_num = 0; flag_menu = 0; flash_write = 0; stm32_Init (); uart1_communication(); uart2_report(); ControlCircuit_Init(); // 初始化12V控制IO // data_init(); LED_ON; for (i=0;i<MILLISECOND*64*10;i++){} // 这段延时可省去: LED_OFF; VAL_ON; // 开启12V输出 Voltage12V_Control(1); // 关闭12V输出 //Voltage12V_Control(0); // I2CInitMasterMode(); // I2CMasterWrite(I2C1,US6300_ADDR, 0x06, 0, buf_us6300); for (i=0;i<500000;i++){}; // 这段延时可导致标定时通信正常;但有时,在线仿真时没有此延时,EEPROM无法通过; // I2CMasterWrite(I2C1,US6300_ADDR, 0x50, 0, buf_us6300); // for (i=0;i<500;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x30, 0, buf_us6300); // for (i=0;i<500;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0xAA, 0, buf_us6300); // for (i=0;i<500000;i++){} // 这段延时可导致标定时通信正常;但有时,在线仿真时没有此延时,EEPROM无法通过; // IWDG->KR = 0xAAAA; // 刷新看门狗IWDG ;写入0xAAAA=装入重载值; IWDG->KR = 0xCCCC; // 启动看门狗; IWDG->KR = 0xAAAA; // 刷新看门狗IWDG; 写入0xAAAA=装入重载值; // I2CMasterWrite(I2C1,US6300_ADDR, 0xAA, 0, buf_us6300);//读第一次数据时必须唤醒3次 // for (i=0;i<500000;i++){} // 这段延时可导致标定时通信正常;但有时,在线仿真时没有此延时,EEPROM无法通过; // IWDG->KR = 0xAAAA; // 刷新看门狗IWDG ;写入0xAAAA=装入重载值; // ***************************************************** while(1) { IWDG->KR = 0xAAAA; // 刷新看门狗IWDG ;写入0xAAAA=装入重载值? if(flag_menu) { // I2CMasterWrite(I2C1,US6300_ADDR, 0x50, 0, buf_us6300); // for (i=0;i<5000;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x50, 0, buf_us6300); // for (i=0;i<5000;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x30, 0, buf_us6300); // for (i=0;i<5000;i++){}; // I2CMasterRead1_6300(I2C1,US6300_ADDR, 3, buf_us6300); // atm = ((buf_us6300[0]&0x0f)*256*256 + buf_us6300[1]*256 + buf_us6300[2])/1000.0; //value/10=hpa,kpa/6.895=psi,hpa/6.895=psi*10; // for (i=0;i<5000;i++){}; // I2CMasterWrite(I2C1,US6300_ADDR, 0x32, 0, buf_us6300); //温度 // for (i=0;i<5000;i++){}; // I2CMasterRead1_6300(I2C1,US6300_ADDR, 3, buf_us6300); // temperature = ((buf_us6300[0]&0x0f)*256*256 + buf_us6300[1]*256 + buf_us6300[2])/100.0; flag_menu = 0; } } } // ***************************************************************************************** // 准备常规报 // ***************************************************************************************** void report2_format(void) { uint32_t i,j; uint8_t temp, temp_AAA[4], temp2_AAA[20]; uint16_t temp_u16; uint32_t temp_u32; union AAA { float f[5] ; u8 u8_[20]; } convert; // convert.f[0] = (float)o2c/10; convert.f[1] = (float)o2RH/10; convert.f[2] = (float)o2t/10; //--传感器显示此数据 convert.f[3] = (float)o2P/10; convert.f[4] = (float)atm; for (i=0;i<5;i++) //5个浮点 { for (j=0;j<4;j++) temp_AAA[3-j] = convert.u8_[i*4+j]; for (j=0;j<4;j++) temp2_AAA[i*4+j] = temp_AAA[j]; } flag_preparing_report=1; //防止在变更过程中发送 for (i=0;i<20;i++) report8[i+4] = temp2_AAA[i]; //利用union将浮点转到report8中; report8[0]=0x16; report8[1]=0x09; report8[2]=0x01; report8[3]=sensor_num-1; temp = 0; for(i=0;i<24;i++) temp += report8[i]; report8[24] = 0x00 - temp; //计算校验字; for (i=0;i<25;i++) USART2_TXbuffer[i] = report8[i]; //将report8拷贝; report8[i] flag_preparing_report = 0; } // ******************************************************************************* // auto_sending自动发送浓度 // ******************************************************************************* void auto2_sending(void) //正常检测时,自动发送检测数据----复核时模式应该还是calibration, 符合完成后才改成NORMAL; { if(flag_preparing_report==0) //防护措施:防止数据准备未完成时发送; { DMA_Cmd(DMA1_Channel4, DISABLE); DMA1_Channel4->CMAR = (u32)&USART2_TXbuffer; DMA1_Channel4->CNDTR = USART2_TXtotal; //DMA通道的DMA缓存的大小 DMA_Cmd(DMA1_Channel4, ENABLE); } } void uart1_communication(void) { uint16_t temp_16; //GPIO端口设置 DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; UART_InitTypeDef UART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE); //使能UART2 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //开启GPIOA时钟 //UART1 NVIC 配置 //UART 初始化设置 GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1); uart1_rate = 9600; UART_InitStructure.UART_BaudRate = uart1_rate;//串口波特率 USART1_TXtotal = 4; USART1_RXtotal = 12; UART_InitStructure.UART_WordLength = UART_WordLength_8b;//字长为8位数据格式 UART_InitStructure.UART_StopBits = UART_StopBits_1;//一个停止位 UART_InitStructure.UART_Parity = UART_Parity_No;//无奇偶校验位 UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;//无硬件数据流控制 UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式 UART_Init(UART1, &UART_InitStructure); //初始化串口1 UART_Cmd(UART1, ENABLE); //使能串口1 //UART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //UART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 // printf("UART OK!\r\n"); //----------UART1_DMA配置部分------------------- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel2); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(UART1->TDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_TXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = USART1_TXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel2, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) &(UART1->RDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_RXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,赐馍栌读取发送到内存 DMA_InitStructure.DMA_BufferSize = USART1_RXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel3, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel2_3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(DMA1_Channel2,DMA_IT_TC,ENABLE); // UART_DMACmd(UART1,UART_DMAReq_EN,ENABLE); //使能uart1 DMA DMA_ITConfig(DMA1_Channel3,DMA_IT_TC,ENABLE); UART_DMACmd(UART1,UART_DMAReq_EN,ENABLE); //使能uart1 DMA // DMA_Cmd(DMA1_Channel4, ENABLE); DMA_Cmd(DMA1_Channel3, ENABLE); } void uart2_report(void) { uint16_t temp_16; //GPIO端口设置 DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; UART_InitTypeDef UART_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART2, ENABLE); //使能UART2 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //开启GPIOA时钟 //UART1 NVIC 配置 //UART 初始化设置 GPIO_PinAFConfig(GPIOA,GPIO_PinSource2,GPIO_AF_1); GPIO_PinAFConfig(GPIOA,GPIO_PinSource3,GPIO_AF_1); uart2_rate = 115200; UART_InitStructure.UART_BaudRate = uart2_rate;//串口波特率 USART2_TXtotal = 25; USART2_RXtotal = 8; UART_InitStructure.UART_WordLength = UART_WordLength_8b;//字长为8位数据格式 UART_InitStructure.UART_StopBits = UART_StopBits_1;//一个停止位 UART_InitStructure.UART_Parity = UART_Parity_No;//无奇偶校验位 UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;//无硬件数据流控制 UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式 UART_Init(UART2, &UART_InitStructure); //初始化串口1 UART_Cmd(UART2, ENABLE); //使能串口1 //UART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 //UART1_RX GPIOA.10初始化 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 // printf("UART OK!\r\n"); //----------UART1_DMA配置部分------------------- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //使能DMA传输 DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(UART2->TDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_TXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //数据传输方向,从内存读取发送到外设 DMA_InitStructure.DMA_BufferSize = USART2_TXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel4, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) &(UART2->RDR); //DMA外设ADC基地址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_RXbuffer; //DMA内存基地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向,赐馍栌读取发送到内存 DMA_InitStructure.DMA_BufferSize = USART2_RXtotal; //DMA通道的DMA缓存的大小 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //数据宽度为8位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //工作在正常缓存模式 DMA_InitStructure.DMA_Priority = DMA_Priority_Low; //DMA通道 x拥有中优先级 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x没有设置为内存到内存传输 DMA_Init(DMA1_Channel5, &DMA_InitStructure); //根据DMA_InitStruct中指定的参数初始化DMA的通道UART1_Tx_DMA_Channel所标识的寄存器 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE); // UART_DMACmd(UART1,UART_DMAReq_EN,ENABLE); //使能uart1 DMA DMA_ITConfig(DMA1_Channel5,DMA_IT_TC,ENABLE); UART_DMACmd(UART2,UART_DMAReq_EN,ENABLE); //使能uart1 DMA // DMA_Cmd(DMA1_Channel4, ENABLE); DMA_Cmd(DMA1_Channel5, ENABLE); } //** //矩阵切换 //** void on_off(uint8_t num) { uint8_t board, sensor_num; board = num%128/16; sensor_num = num%16; switch(board) //切换板编号 { case 0: EN0_ON; EN1_OFF; EN2_OFF; EN3_OFF; break; case 1: EN0_OFF; EN1_ON; EN2_OFF; EN3_OFF; break; case 2: EN0_OFF; EN1_OFF; EN2_ON; EN3_OFF; break; case 3: EN0_OFF; EN1_OFF; EN2_OFF; EN3_ON; break; } switch(sensor_num) //传感器编号 { case 15: A0_ON; A1_ON; A2_ON; A3_ON; break; case 14: A0_OFF; A1_ON; A2_ON; A3_ON; break; case 13: A0_ON; A1_OFF; A2_ON; A3_ON; break; case 12: A0_OFF; A1_OFF; A2_ON; A3_ON; break; case 11: A0_ON; A1_ON; A2_OFF; A3_ON; break; case 10: A0_OFF; A1_ON; A2_OFF; A3_ON; break; case 9: A0_ON; A1_OFF; A2_OFF; A3_ON; break; case 8: A0_OFF; A1_OFF; A2_OFF; A3_ON; break; case 7: A0_ON; A1_ON; A2_ON; A3_OFF; break; case 6: A0_OFF; A1_ON; A2_ON; A3_OFF; break; case 5: A0_ON; A1_OFF; A2_ON; A3_OFF; break; case 4: A0_OFF; A1_OFF; A2_ON; A3_OFF; break; case 3: A0_ON; A1_ON; A2_OFF; A3_OFF; break; case 2: A0_OFF; A1_ON; A2_OFF; A3_OFF; break; case 1: A0_ON; A1_OFF; A2_OFF; A3_OFF; break; case 0: A0_OFF; A1_OFF; A2_OFF; A3_OFF; break; } } //电压采样 void Get_Adc_Average(void) { uint8_t i; uint16_t temp_v, Temp_average_float; } //正常显示 void display(void) { } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * @param file: pointer to the source file name * @param line: assert_param error line source number * @retval None */ void assert_failed(uint8_t* file, uint32_t line) { /* User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ /* Infinite loop */ while (1) { } } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ #include "user.h" //------全局变量定义------- //------全局变量定义------- void I2C_Configuration(void); //void ADC_CH_DMA_Config(void); /*配置DMA4_5的中断*/ void NVIC_Config() { NVIC_InitTypeDef NVIC_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_5_IRQn;//DMA1_Channel4_5_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_Init(&NVIC_InitStructure); } /*配置DMA4_5的中断*/ void Delay(uint32_t nCount) { while (nCount != 0) { nCount--; } } void uart_putc(unsigned char c) { while(!((UART1->ISR)&(1<<7))); UART1->TDR=c; } void uart_puts(char *s ) { while (*s) uart_putc(*s++); } void GPIO_INIT(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_11|GPIO_Pin_12; //PA6-背光脚、PA7-STB、PA12-喇叭控制 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_5; //PB0-CLK、PB1-DIO、PB5-LED GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); PVCC_ON; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4; //PB4-P_CS GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } /** * @brief Configures system clock after wake-up from STOP: enable HSE, PLL * and select PLL as system clock source. * @param None * @retval None */ void SYSCLKConfig_STOP(void) { /* After wake-up from STOP reconfigure the system clock */ /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Wait till HSE is ready */ while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) {} /* Enable PLL */ RCC_PLLCmd(ENABLE); /* Wait till PLL is ready */ while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) {} /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); /* Wait till PLL is used as system clock source */ while (RCC_GetSYSCLKSource() != 0x08) {} } //------------------------------------------------ //-----------------定时器配置--------------------- void stm32_TimerSetup (void) { //注意:TIMx中断可轻易使能,因为如果TIMx已经启动,会自动引发中断,造成CPU无法跳到下一个断点;其中的原因还甚明了; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE ); //开启tim14时钟 TIM16->CR1 = 0; // reset command register 1 TIM16->PSC = 1000; // set prescaler;TIM3_CLK=72MHz/1=72MHz TIM16->ARR = 500*FCLK_H_MHZ-1; // 100uS TIM16->DIER |=1<<0; // enable interrupt NVIC_InitStructure.NVIC_IRQChannel = TIM16_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority =0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM16->CR1 |= 1<<0; // 启动timer2 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM14, ENABLE ); //开启tim17时钟 ---25ms TIM14->CR1 = 0; // reset command register 1 TIM14->PSC = 1000; // set prescaler;TIM3_CLK=72MHz/1=72MHz TIM14->ARR = 7*FCLK_H_MHZ-1; // 100uS TIM14->DIER |=1<<0; // enable interrupt NVIC_InitStructure.NVIC_IRQChannel = TIM14_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority =0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM14->CR1 |= 1<<0; // 启动timer2 } ///*---------------------------------------------------------------------------- // set HSI as SystemCoreClock (HSE is not populated on STM32L-Discovery board) // *----------------------------------------------------------------------------*/ void SystemCoreClockSetHSE(void) { RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Enable HSE */ while ((RCC->CR & RCC_CR_HSERDY) == 0); /* Wait for HSE Ready */ RCC->CFGR = RCC_CFGR_SW_HSE; /* HSE is system clock */ while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSE); /* Wait for HSE used as system clock */ // FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // FLASH_SetLatency(FLASH_Latency_1); FLASH->ACR = FLASH_ACR_PRFTBE; /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_Latency_2; /* Flash 1 wait state */ RCC->CFGR |= RCC_CFGR_HPRE_DIV1; /* HCLK = SYSCLK */ RCC->CFGR |= RCC_CFGR_PPRE1_DIV1; /* PCLK = HCLK */ RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; /* PCLK = HCLK */ RCC->CR &= ~RCC_CR_PLLON; /* Disable PLL */ /*PLL configuration: = HSE * 3 = 24 MHz */ // RCC->CFGR &= ~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL); RCC->CFGR |=1<<16; RCC->CFGR &=~(1<<17); RCC->CR &=~(0x3f<<26); RCC->CR |=5 << 26; //设置PLL值 2~16 // RCC->CFGR |= (RCC_CFGR_PLLSRC_1 | RCC_CFGR_PLLMULL3); RCC->CR |= RCC_CR_PLLON; /* Enable PLL */ while((RCC->CR & RCC_CR_PLLRDY) == 0) __NOP(); /* Wait till PLL is ready */ RCC->CFGR &= ~RCC_CFGR_SW; /* Select PLL as system clock source */ RCC->CFGR |= RCC_CFGR_SW_PLL; while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL); /* Wait till PLL is system clock src */ // RCC->CR &= ~RCC_CR_HSION; /* Disable HSI /必须配置完成才能关闭内部时钟*/ } //---------------------------------------------------------------------------- // STM32 Independent watchdog setup. // initializes the IWDG register //---------------------------------------------------------------------------- void stm32_IwdgSetup (void) { RCC->CSR|= (1<<0); // LSI enable, necessary for IWDG while ((RCC->CSR& (1<<1)) == 0); // wait till LSI is ready IWDG->KR = 0x5555; //写入0x5555表示允许访问IWDG->PR, IWDG->RLR while ((IWDG->SR& (1<<0)) == 1); IWDG->PR = 4; //预分频系数:0=/4;1=/8;2=/16;3=/32;4=/64;5=/128;6=/256;7=/256 while ((IWDG->SR& (1<<1)) == 1); IWDG->RLR = 0xFFF; // 重载值(0-4095)=(超时周期*时钟频率-1)=; // 重载值= 3秒*128-1=383 IWDG->KR = 0xAAAA; // 写入0xAAAA=装入重载值; //IWDG->KR.all = 0xCCCC; // 启动看门狗; } // end of stm32_IwdgSetup /** * @brief ADC1 channel with DMA configuration * @param None * @retval None */ void ADC_CH_DMA_Config(void) { ADC_InitTypeDef ADC_InitStruct; DMA_InitTypeDef DMA_InitStruct; GPIO_InitTypeDef GPIO_InitStruct; /* ADC1 DeInit */ ADC_DeInit(ADC1);//主要功能:先使能ADC1时钟,再失能ADC1时钟 /* Enable GPIOA clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); /* Configure PA.01 as analog input */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; //模拟输入和浮空输入 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // PC1,输入时用设置速率 /* DMA1 clock enable */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE); /* DMA1 Channel1 Config */ DMA_DeInit(DMA1_Channel1); // DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;//stm32f030用 DMA_InitStruct.DMA_PeripheralBaseAddr = (u32)&(ADC1->ADDATA); DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&adc_v; DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStruct.DMA_BufferSize =1; DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;// /* ADC DMA request in circular mode */ DMA_InitStruct.DMA_Priority = DMA_Priority_High; DMA_InitStruct.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStruct); /* DMA1 Channel1 enable */ DMA_Cmd(DMA1_Channel1, ENABLE); /* Enable ADC_DMA */ ADC_DMACmd(ADC1, ENABLE); /* Initialize ADC structure */ ADC_StructInit(&ADC_InitStruct); /* ADC1 Periph clock enable */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits */ ADC_InitStruct.ADC_PRESCARE = ADC_PCLK2_PRESCARE_2; ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; ADC_InitStruct.ADC_Mode = ADC_Mode_Continuous_Scan; // ADC_InitStruct.ADC_TRGEN = ADC_TRG_Disable;//使用外部触发信号启动转换 ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; ADC_Init(ADC1, &ADC_InitStruct); /*屏蔽所有通道*/ ADC1->ADCHS&=0xffffffe00; /*使能选中通道,后面参数保留*/ ADC_RegularChannelConfig(ADC1, ADC_Channel_1 ,0 , ADC_SampleTime_13_5Cycles); // ADC_VrefintCmd(ENABLE); // ADC1->ADCFG|=0x04; 手册说该位保留,必须为0; ADC_ExternalTrigConvCmd(ADC1,DISABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE); /* Wait the ADCEN falg */ // while(!ADC_GetFlagStatus(ADC1, RESET)); /* ADC1 regular Software Start Conv */ ADC_SoftwareStartConvCmd(ADC1,ENABLE); } //------------------------------------------------------------------ // STM32 embedded Flash interface setup. // initializes the ACR register //------------------------------------------------------------------ void stm32_EfiSetup (void) { // u32 temp; FLASH->ACR = 0x00000012; // set access control register;__EFI_ACR_Val=0x00000012 FLASH->ACR|= 2<<0; //0=SYSCLK<24Mhz,1=<24<SYSCLK<48Mhz,2=48<SYSCLK<72Mhz; // temp= FLASH->ACR.all; } //external interrupt initialprocedure void EXTIX_Init(void) { EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);//外部中断,需要使能AFIO时钟 // SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource3); // // EXTI_InitStructure.EXTI_Line=EXTI_Line3; // EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发 // EXTI_InitStructure.EXTI_LineCmd = ENABLE; // EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource11); EXTI_InitStructure.EXTI_Line=EXTI_Line11; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource15); EXTI_InitStructure.EXTI_Line=EXTI_Line15; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发 EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 NVIC_InitStructure.NVIC_IRQChannel = EXTI4_15_IRQn; //使能按键所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPriority = 0x02; //子优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 // NVIC_InitStructure.NVIC_IRQChannel = EXTI2_3_IRQn; //使能按键所在的外部中断通道 // NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01; //子优先级1 // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 // NVIC_Init(&NVIC_InitStructure); } void stm32_Init () { // stm32_EfiSetup(); //已经在MM32F031系统时钟配置中配置过 SystemCoreClockSetHSE(); //SYSTICK_INIT(); //SYSTICK一定要谨慎使用,用好会和DEBUG冲突,貌似没什么用,屏蔽又会报错 GPIO_INIT(); // USART_INIT(); // stm32_dmaSetup(); stm32_TimerSetup(); //RTC_Config(); //I2C_Configuration(); stm32_IwdgSetup(); // ADC_CH_DMA_Config(); // EXTIX_Init(); } /** ****************************************************************************** * @file PWR_STOP/stm32f0xx_it.c * @author MCD Application Team * @version V1.0.1 * @date 11-October-2013 * @brief Main Interrupt Service Routines. * This file provides template for all exceptions handler and * peripherals interrupt service routine. ****************************************************************************** * @attention * * <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2> * * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "MM32F031xxn.h" #include "user.h" #include "main.h" //************STM32F1函数以及变量定义******************************************* //****************************************************************************** /** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { } /** * @brief This function handles Hard Fault exception. * @param None * @retval None */ void HardFault_Handler(void) { /* Go to infinite loop when Hard Fault exception occurs */ while (1) { } } /** * @brief This function handles SVCall exception. * @param None * @retval None */ void SVC_Handler(void) { } /** * @brief This function handles PendSVC exception. * @param None * @retval None */ void PendSV_Handler(void) { } /** * @brief This function handles SysTick Handler. * @param None * @retval None */ void SysTick_Handler(void) { // STM_EVAL_LEDToggle(LED3); // TimingDelay--; } //void TIM17_IRQHandler(void) //{ // // TIM17->SR&= ~(1<<0); //清除中断标志;UIF // if(Flag_rx_dma==1) // { // Dma_clear_delay++; // } // if(Dma_clear_delay==7) //RX接收到数据后35ms开始更新dma防止干扰下次接收 // { // DMA_Cmd(DMA1_Channel5, DISABLE); /* Disable DMA1 Channel4 transfer */ // DMA1_Channel5->CNDTR=USART1_RXtotal; // DMA_Cmd(DMA1_Channel5, ENABLE); /* Enable DMA1 Channel4 transfer */ // //DMA1->IFCR|=1<<16; //清除DMA通道4的全部中断标志位; // Dma_clear_delay=0; // Flag_rx_dma=0; // } //} /******************************************************************************/ /* STM32F0xx Peripherals Interrupt Handlers */ /* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ /* available peripheral interrupt handler's name please refer to the startup */ /* file (startup_stm32f0x8.s). */ /******************************************************************************/ /** * @brief This function handles RTC Auto wake-up interrupt request. * @param None * @retval None */ void TIM16_IRQHandler(void) { GPIO_InitTypeDef GPIO_InitStructure; uint16_t temp; TIM16->SR&= ~(1<<0); //清除中断标志;UIF counter_cycle++; if(counter_cycle%2==1) { LED_ON; if(((atm<45)||(atm>155))&&((o2P<450)||(o2P>1550))) { BEEP_ON; } } else { LED_OFF; BEEP_OFF; } if(counter_cycle==20) { TIM14->CR1 = 0; // reset command register 1 TIM14->ARR = 20*FCLK_H_MHZ-1; // 30ms TIM14->CR1 |= 1<<0; // 启动timer2 } // if(rx_flag>3) // { // DMA_Cmd(DMA1_Channel5, DISABLE); /* Disable DMA1 Channel4 transfer */ // DMA1_Channel5->CMAR = (u32)&USART1_RXbuffer; // DMA1_Channel5->CNDTR=USART1_RXtotal; // DMA_Cmd(DMA1_Channel5, ENABLE); /* Enable DMA1 Channel4 transfer */ // } flag_menu = 1; } void TIM14_IRQHandler(void) { uint8_t i; TIM14->SR&= ~(1<<0); //清除中断标志;UIF if(counter_cycle>=20) //重置DMA { DMA_Cmd(DMA1_Channel3, DISABLE); /* Disable DMA1 Channel4 transfer */ DMA1_Channel3->CMAR = (u32)&USART1_RXbuffer; DMA1_Channel3->CNDTR=USART1_RXtotal; DMA_Cmd(DMA1_Channel3, ENABLE); /* Enable DMA1 Channel4 transfer */ } else { DMA_Cmd(DMA1_Channel3, DISABLE); /* Disable DMA1 Channel4 transfer */ } if(sensor_num<64) { on_off(sensor_num); //此处有BUG for(i=0;i<100;i++){}; sensor_num++; //每隔25ms查询一次,如果没有收到数据,则报送 USART1_TXbuffer[0] = 0x11; USART1_TXbuffer[1] = 0x01; USART1_TXbuffer[2] = 0x01; USART1_TXbuffer[3] = 0xED; DMA_Cmd(DMA1_Channel2, DISABLE); DMA1_Channel2->CMAR = (u32)&USART1_TXbuffer; DMA1_Channel2->CNDTR = USART1_TXtotal; //DMA通道的DMA缓存的大小 DMA_Cmd(DMA1_Channel2, ENABLE); } else sensor_num = 0; cntr_tim14++; display_flag = 1; } void TIM3_IRQHandler(void) { TIM3->SR&= ~(1<<0); //清除中断标志;UIF } /** * @brief This function handles DMA1 Channel 1 interrupt request. * @param None * @retval None */ void DMA1_Channel4_5_IRQHandler(void) { if(DMA_GetITStatus(DMA1_IT_TC4)) { DMA_ClearITPendingBit(DMA1_IT_GL4); //清除DMA通道4的全部中断标志位; DMA_Cmd(DMA1_Channel4, DISABLE); /* Enable DMA1 Channel4 transfer */ } if(DMA_GetITStatus(DMA1_IT_TC5)) { DMA_ClearITPendingBit(DMA1_IT_GL5); // USART_DMACmd(USART1,USART_DMAReq_Tx,DISABLE); //USART1 关闭DMA发送使能; /*--------发送数据前先更新接收DMA防止接收前的干扰*/ } DMA_Cmd(DMA1_Channel5, DISABLE); /* Disable DMA1 Channel4 transfer */ DMA1_Channel5->CMAR = (u32)&USART2_RXbuffer; DMA1_Channel5->CNDTR=USART2_RXtotal; DMA_Cmd(DMA1_Channel5, ENABLE); /* Enable DMA1 Channel4 transfer */ } //------------------------------------------------------------------------------ // DMA1_Channel2 Interrupt Handler ----TIM1_CH1的PWM输入捕获比较; //------------------------------------------------------------------------------ //void DMA1_Channel2_IRQHandler (void) void DMA1_Channel2_3_IRQHandler (void) { uint8_t temp, i; uint16_t temp_o2c; if(DMA_GetITStatus(DMA1_IT_TC2)) { DMA_ClearITPendingBit(DMA1_IT_GL2); //清除DMA通道的中断标志位; DMA_Cmd(DMA1_Channel2, DISABLE); /* Enable DMA1 Channel4 transfer */ } if(DMA_GetITStatus(DMA1_IT_TC3)) { DMA_ClearITPendingBit(DMA1_IT_GL3); //清除DMA通道的中断标志位; rx_flag++; temp = 0; for(i=0; i<12; i++) temp += USART1_RXbuffer[i]; if((temp==0)&&(USART1_RXbuffer[0]==0x16)&&(USART1_RXbuffer[1]==0x09)&&(USART1_RXbuffer[2]==0x01)) { o2c = USART1_RXbuffer[3]*256+USART1_RXbuffer[4]; o2RH = USART1_RXbuffer[5]*256+USART1_RXbuffer[6]; o2t = USART1_RXbuffer[7]*256+USART1_RXbuffer[8]; o2P = USART1_RXbuffer[9]*256+USART1_RXbuffer[10]; rx_flag = 0; } if((display_flag)&&(counter_cycle>20)) { report2_format(); auto2_sending(); display_flag = 0; } } DMA_Cmd(DMA1_Channel3, DISABLE); /* Disable DMA1 Channel4 transfer */ DMA1_Channel3->CMAR = (u32)&USART1_RXbuffer; DMA1_Channel3->CNDTR=USART1_RXtotal; DMA_Cmd(DMA1_Channel3, ENABLE); /* Enable DMA1 Channel4 transfer */ } /*void PPP_IRQHandler(void) { }*/ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ 根据上面三个.c文件,增加以下功能串口2是PA2(TX)和PA3(RX),串口1是PA9(TX)和PA10(RX),检测板接收到电脑发送启动指令FF FF 10 00 00 25 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF后将连接传感器的串口1波特率设置为9600,DMA接收12个字节,发送4个字节,并打开电源,等待5秒钟后,向每个传感器连续发送2遍11 AA 55 F0,四个字节每遍间隔时间5秒,发送2遍之后重新设置串口1波特率为250000,DMA接收30个字节,发送30个字节.接收到以下指令后浓度封底:0A 0B AA 01 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 01 02 03 04 FF 浓度封底:0A 0B AA 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 01 02 03 04 FF 流量0点校准:FF FF 10 00 00 8E 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF 高浓度校准:FF FF 10 00 00 7E 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 42 B7 D1 EC FF FF 流量校准:FF FF 10 00 00 8D 00 1E 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF 报送数据:FF FF 10 00 00 22 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 00 00 FF FF 直接通过串口1发送给传感器,并接收传感器回复的数据,数据校验要做好 通过串口2发送给电脑,这个是检测板的代码,其他功能变,只改变,需要改变的部分,屏蔽的部分要删除,计时用定时器,分别生成三个,c文件
11-01
import os import sys import cv2 from cv2 import resize import numpy as np import matplotlib.pyplot as plt import argparse from PIL import Image import torch import src.utils as utils import src.dataset as dataset import crnn.seq2seq as crnn def seq2seq_decode(encoder_out, decoder, decoder_input, decoder_hidden, max_length): decoded_words = [] alph = "ABCDEFGHIJKLMNOPQRSTUVWXYZŽŠŪ-\'" converter = utils.ConvertBetweenStringAndLabel(alph) prob = 1.0 for di in range(max_length): decoder_output, decoder_hidden, decoder_attention = decoder(decoder_input, decoder_hidden, encoder_out) probs = torch.exp(decoder_output) _, topi = decoder_output.data.topk(1) ni = topi.squeeze(1) decoder_input = ni prob *= probs[:, ni] if ni == utils.EOS_TOKEN: break else: decoded_words.append(converter.decode(ni)) words = ''.join(decoded_words) prob = prob.item() return words, prob def find_median(array_vals): array_vals.sort() mid = len(array_vals) // 2 return array_vals[mid] def detect_centerline(array_vals): max_val = max(array_vals) index_list = [index for index in range(len(array_vals)) if array_vals[index] == max_val] return find_median(index_list) def rotate_image(image, angle): image_center = tuple(np.array(image.shape[1::-1]) / 2) rot_mat = cv2.getRotationMatrix2D(image_center, angle, 1.0) result = cv2.warpAffine(image, rot_mat, image.shape[1::-1], flags=cv2.INTER_LINEAR) return result def extract_peak_ranges_from_array(array_vals, minimum_val=100, minimum_range=2): start_i = None end_i = None peak_ranges = [] for i, val in enumerate(array_vals): if val >= minimum_val and start_i is None: start_i = i elif val >= minimum_val and start_i is not None: pass elif val < minimum_val and start_i is not None: end_i = i if end_i - start_i > minimum_range: peak_ranges.append((start_i, end_i)) start_i = None end_i = None elif val < minimum_val and start_i is None: pass else: raise ValueError("Cannot Parse") return peak_ranges parser = argparse.ArgumentParser() parser.add_argument('--img_path', type=str, default='', help='the path of the input image') parser.add_argument('--rot_angle', type=int, default=0, help='the global rotation image') parser.add_argument('--padding', type=int, default=10, help='paddings at the head of the image') parser.add_argument('--block_size', type=int, default=33, help='threshold for binarizing image, odd number only') parser.add_argument('--threshold', type=int, default=32, help='radius to calculate the average for thresholding, even number only') parser.add_argument('--vertical_minimum', type=int, default=800, help='minimal brightness of each VERTICAL line') parser.add_argument('--word_minimum', type=int, default=200, help='minimal brightness of each WORD') parser.add_argument('--blur', type=bool, default=False, help='apply blur to words?') parser.add_argument('--pretrained', type=int, default=1, help='which pretrained model to use') cfg = parser.parse_args() def main(): global_rot_angle = cfg.rot_angle global_padding = cfg.padding imagename = cfg.img_path if cfg.pretrained == 0: my_encoder = "./model/encoder_0.pth" my_decoder = "./model/decoder_0.pth" elif cfg.pretrained == 1: my_encoder = "./model/encoder_1.pth" my_decoder = "./model/decoder_1.pth" else: sys.exit("Unknown Pretrained Model!") print("Analyzing: "+imagename) alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZŽŠŪ-\'" print("Using Möllendorff Alphabet List: " + alphabet + "\n") # len(alphabet) + SOS_TOKEN + EOS_TOKEN num_classes = len(alphabet) + 2 transformer = dataset.ResizeNormalize(img_width=480, img_height=64) image_color = cv2.imread(imagename) image_shape = (image_color.shape[0], image_color.shape[1]) image_binary = cv2.cvtColor(image_color, cv2.COLOR_BGR2GRAY) image = cv2.rotate(image_binary, cv2.ROTATE_90_COUNTERCLOCKWISE) adaptive_threshold = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, cfg.block_size, cfg.threshold) adaptive_threshold = rotate_image(adaptive_threshold, global_rot_angle) adaptive_threshold = cv2.copyMakeBorder(adaptive_threshold, 20, 20, 20, 20, cv2.BORDER_CONSTANT, 0) adaptive_threshold = adaptive_threshold[10:adaptive_threshold.shape[0]-10, 10:adaptive_threshold.shape[1]-10] image_blur = cv2.GaussianBlur(adaptive_threshold,(3,3),cv2.BORDER_DEFAULT) cv2.imshow('Binary Image', cv2.rotate(adaptive_threshold, cv2.ROTATE_90_CLOCKWISE)) cv2.waitKey(1) vertical_sum = np.sum(image_blur, axis=1) peak_ranges = extract_peak_ranges_from_array(vertical_sum,minimum_val=cfg.vertical_minimum,minimum_range=5) img_display = np.copy(adaptive_threshold) #peak_ranges.append((peak_ranges[-1][1],adaptive_threshold.shape[0])) peak_ranges.reverse() horizontal_peak_ranges2d = [] for peak_range in peak_ranges: start_y = 0 end_y = img_display.shape[1] image_x = image_blur[peak_range[0]:peak_range[1], start_y:end_y] horizontal_sum = np.sum(image_x,axis = 0) # plt.plot(horizontal_sum, range(horizontal_sum.shape[0])) # plt.gca().invert_yaxis() # plt.show() horizontal_peak_ranges = extract_peak_ranges_from_array(horizontal_sum,minimum_val=cfg.word_minimum,minimum_range=5) horizontal_peak_ranges2d.append(horizontal_peak_ranges) for hor in horizontal_peak_ranges: cv2.rectangle(img_display, (hor[0], peak_range[0]), (hor[1], peak_range[1]), 140, 1) word_piece = adaptive_threshold[peak_range[0]:peak_range[1],hor[0]:hor[1]] if cfg.blur: word_piece = cv2.GaussianBlur(word_piece,(1,1),cv2.BORDER_DEFAULT) else: pass image_dimension = (word_piece.shape[0], word_piece.shape[1]) #cv2.imshow('Words', word_piece) #print(word_piece.shape) if image_dimension[0] < 30 or image_dimension[1] < 20: pass else: factor = 1 image_resized = cv2.resize(word_piece, (int(image_dimension[1]*factor),int(image_dimension[0]*factor)), interpolation = cv2.INTER_AREA) hor_sum = np.sum(image_resized, axis=1) ctr_line = detect_centerline(hor_sum) image_dimension_new = (image_resized.shape[0], image_resized.shape[1]) add_padding = max([ctr_line, image_dimension_new[0]-ctr_line]) # cv2.imshow('current Image', image_resized) # cv2.waitKey(0) if image_dimension_new[1]<=500: padded = cv2.copyMakeBorder(image_resized, add_padding-ctr_line, add_padding-image_dimension_new[0]+ctr_line, 0, 0, cv2.BORDER_CONSTANT, 0) else: padded = image_resized factor = 64/padded.shape[0] padded = cv2.resize(padded, (int(padded.shape[1]*factor),int(padded.shape[0]*factor)), interpolation = cv2.INTER_AREA) padded = cv2.copyMakeBorder(padded, 0, 0, global_padding, 480 - global_padding - padded.shape[0], cv2.BORDER_CONSTANT, 0) padded = Image.fromarray(np.uint8(padded)).convert('L') padded = transformer(padded) padded = padded.view(1, *padded.size()) padded = torch.autograd.Variable(padded) encoder = crnn.Encoder(1, 1024) # no dropout during inference decoder = crnn.Decoder(1024, num_classes, dropout_p=0.0, max_length=121) map_location = 'cpu' encoder.load_state_dict(torch.load(my_encoder, map_location=map_location)) decoder.load_state_dict(torch.load(my_decoder, map_location=map_location)) encoder.eval() decoder.eval() encoder_out = encoder(padded) max_length = 121 decoder_input = torch.zeros(1).long() decoder_hidden = decoder.initHidden(1) words, prob = seq2seq_decode(encoder_out, decoder, decoder_input, decoder_hidden, max_length) print(words+" ", end = '') print("\n") cv2.destroyAllWindows() cv2.imshow('Current Line', cv2.rotate(img_display, cv2.ROTATE_90_CLOCKWISE)) cv2.waitKey(1) #input("Reading Completed, Press Any Key to Exit. Ambula Baniha.") # color = (0, 0, 255) # for i, peak_range in enumerate(peak_ranges): # for horizontal_range in horizontal_peak_ranges2d[i]: # x = peak_range[0] # y = horizontal_range[0] # w = peak_range[1] # h = horizontal_range[1] # patch = adaptive_threshold[x:w,y:h] # cv2.rectangle(img_display, (y,x), (h,w), 255, 2) # # print(cnt) # # cv2.imwrite("/Users/zhuohuizhang/Downloads/ManchuOCR/Data/"+fontname+"/Result/"+'%d' %cnt + '.jpg', patch) # cnt += 1 # # cv2.imshow('Vertical Segmented Image', line_seg_blur) # cv2.waitKey(0) if __name__ == "__main__": main() 上面的代码会打包成readmanchu.exe,readmanchu.exe运行时具有参数:--img_path(该参数是必填,该选项是选择图片)、--rot_angle(旋转角度,默认是0,选填)、--padding(图形头部的填充,默认值是10,选填)、--block_size(图像二值化阈值,仅限奇数,默认值是33,选填)、--threshold(计算阈值平均值的半径,仅限偶数,默认值32,选填)、--vertical_minimum(每条垂直线的最小亮度,默认值800,选填)、--word_minimum(每个单词的最小亮度,默认值200,选填)、--blur(对文字应用模糊效果?,默认值False)、----pretrained(使用哪个预训练模型?默认值1,int类型),要求所有参数都是通过键盘输入的方式,因此根据这个readmanchu.exe编写一个新的脚本,新的脚本是图形化的(使用tkinter)方式,新的脚本可以填入readmanchu.exe的参数,然后点击运行后台即可运行readmanchu.exe以及它的参数,并且在输入参数后点击运行即可将readmanchu.exe打印的信息显示出来,并将打印的信息输出到当前文件夹下的.\output\选中图片的名称.txt(自动在当前目录下创建目录和文件),运行readmanchu.exe就相当于调用winodows的cmd命令行然后执行readmanchu.exe以及它的参数,并且要求imp_path可以批量处理图片(多线程);实际运行效果是:(举例) .\readmanchu.exe --img_path .\examples\001.png --rot_angle 0 --padding 10 --block_size 33 --threshold 32 --vertical_minimum 800 --word_minimum 300 --blur False ----pretrained 1 实际就相当于后台调用cmd命令行在执行readmanchu.exe
09-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值