import argparse, math def check_range(value): '''Проверка целочисленных аргументов в диапазоне [1, 2^20-1]''' try: ivalue = int(value) except ValueError: raise argparse.ArgumentTypeError(f'"{value}" не является целым числом') if ivalue < 1 or ivalue >= 2**20: raise argparse.ArgumentTypeError(f'Значение должно быть в диапазоне [1, 2^20-1]') return ivalue def check_rtc_cal_err(rtc_prl, rtc_cal): '''Проверка отсутствия ошибки для заданных RTC_PRL и RTC_CAL''' if rtc_prl == 0 or rtc_cal == 0: return True prediv_s_period = rtc_prl + 1 # Период RTC_PREDIV_S(RTC_DIV) prediv_s_ticks = 2**20 - rtc_cal # Количество тактов RTC_PREDIV_S(RTC_DIV) за один период RTC_PREDIV_A(RTC_20) с учетом калибровки d = math.gcd(prediv_s_period, prediv_s_ticks) # Наибольший общий делитель if d != 1: return True else: return False def print_rtc_cal_table(rtc_prl, rtc_clk): '''Вывод таблицы с допустимыми значениями RTC_CAL''' header_h = f'| {"RTC_CAL":^7} | {"RTC_CLK_CAL, Гц":^19} | {"Калибровка, ppm":^17} | {"Калибровка, сек/сут":^19} |' header_l = f'| {"":^7} | {"":^19} | {"(RTC_PRL+RTC_CAL)":^17} | {"(RTC_PRL+RTC_CAL)":^19} |' separator = '-' * len(header_h) print('\nДопустимые значения RTC_CAL') print(separator) print(header_h) print(header_l) print(separator) for rtc_cal in range(0, 256): if check_rtc_cal_err(rtc_prl, rtc_cal) == True: rtc_clk_cal = rtc_clk - (rtc_clk * rtc_cal) / 2**20 sec_clk = rtc_clk_cal / (rtc_prl + 1) cal_ppm = (sec_clk - 1) * 1E6 cal_sec_per_day = (60 * 60 * 24 * cal_ppm) / 1E6 print(f'| {rtc_cal:<7} | {rtc_clk_cal:<19} | {cal_ppm:<+17.2f} | {cal_sec_per_day:<+19.2f} |') print(separator) def main(): parser = argparse.ArgumentParser(description='Выводит допустимые значения RTC_CAL для заданных RTC_PRL и RTC_CLK', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('RTC_PRL', type=check_range, help='Целое число от 1 до 2^20-1') parser.add_argument('RTC_CLK', type=check_range, help='Целое число от 1 до 2^20-1', nargs='?', default=32768) args = parser.parse_args() print(f'\nRTC_PRL = {args.RTC_PRL}, RTC_CLK = {args.RTC_CLK}') print_rtc_cal_table(args.RTC_PRL, args.RTC_CLK) if __name__ == '__main__': main()